From d81cd01efc4cf6f7d64deac10ec8b33eeec914cb Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 4 Aug 2013 16:58:54 +0000 Subject: [PATCH 01/25] [KERNEL32]: Complete rewrite of CreateProcessInternalW based on Server 2003, instead of the original version that I wrote based on Windows 2000. This new version adds the right CSRSS support for VDM and Wow32, stubs the upcoming support for SxS, uses the new NtCreateProcessEx functionality, adds checks for SDB/Shim/AppCompat, adds checks for SRP (the old AppLocker), adds support for image file execution options, such as large pages and the debugger key, adds licensing checks, adds better path handling using the path APIs that Thomas, Hermes, and Myself re-wrote/improved in Rtl/NTDLL, and a whole lot more. Tested with a bunch of launches, downloads, and apps, and no immediate regressions were seen, but this is 3500 lines of code and nothing is perfect. Please file Jira issues as they come up -- I will maintain & fix this. Will also ask Hermes to start working on the VDM/WoW32 paths for the new NTVDM work that's happening, and I will start looking at SxS. svn path=/trunk/; revision=59637 --- reactos/dll/win32/kernel32/client/proc.c | 2945 ++++++++++++----- reactos/dll/win32/kernel32/client/vdm.c | 3 +- reactos/dll/win32/kernel32/include/kernel32.h | 31 +- 3 files changed, 2143 insertions(+), 836 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index 47d913d07c4..f844b8b17db 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -52,7 +52,6 @@ RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle); /* FUNCTIONS ****************************************************************/ -// NOTE: Code duplicated from BasepDuplicateAndWriteHandle VOID WINAPI StuffStdHandle(IN HANDLE ProcessHandle, @@ -68,7 +67,8 @@ StuffStdHandle(IN HANDLE ProcessHandle, StandardHandle, ProcessHandle, &DuplicatedHandle, - 0, 0, + 0, + 0, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES); if (NT_SUCCESS(Status)) { @@ -83,9 +83,9 @@ StuffStdHandle(IN HANDLE ProcessHandle, BOOLEAN WINAPI -BuildSubSysCommandLine(IN LPWSTR SubsystemName, - IN LPWSTR ApplicationName, - IN LPWSTR CommandLine, +BuildSubSysCommandLine(IN LPCWSTR SubsystemName, + IN LPCWSTR ApplicationName, + IN LPCWSTR CommandLine, OUT PUNICODE_STRING SubsysCommandLine) { UNICODE_STRING CommandLineString, ApplicationNameString; @@ -184,9 +184,9 @@ BasepConfigureAppCertDlls(IN PWSTR ValueName, NTSTATUS WINAPI -BasepIsProcessAllowed(IN PCHAR ApplicationName) +BasepIsProcessAllowed(IN LPWSTR ApplicationName) { - NTSTATUS Status; + NTSTATUS Status, Status1; PWCHAR Buffer; UINT Length; HMODULE TrustLibrary; @@ -250,19 +250,22 @@ BasepIsProcessAllowed(IN PCHAR ApplicationName) else { /* Other systems have a registry entry for this */ - Status = NtOpenKey(&KeyHandle, KEY_READ, &KeyAttributes); - if (NT_SUCCESS(Status)) + Status1 = NtOpenKey(&KeyHandle, KEY_READ, &KeyAttributes); + if (NT_SUCCESS(Status1)) { /* Close it, we'll query it through Rtl */ NtClose(KeyHandle); /* Do the query, which will call a special callback */ - Status = RtlQueryRegistryValues(2, + Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, L"Session Manager", BasepAppCertTable, - 0, - 0); - if (Status == 0xC0000034) Status = STATUS_SUCCESS; + NULL, + NULL); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + Status = STATUS_SUCCESS; + } } } @@ -519,237 +522,6 @@ BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, return STATUS_SUCCESS; } -/* - * Creates the first Thread in a Proces - */ -HANDLE -WINAPI -BasepCreateFirstThread(HANDLE ProcessHandle, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - PSECTION_IMAGE_INFORMATION SectionImageInfo, - PCLIENT_ID ClientId, - DWORD dwCreationFlags) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES LocalObjectAttributes; - POBJECT_ATTRIBUTES ObjectAttributes; - CONTEXT Context; - INITIAL_TEB InitialTeb; - HANDLE hThread; - BASE_API_MESSAGE ApiMessage; - PBASE_CREATE_PROCESS CreateProcessRequest = &ApiMessage.Data.CreateProcessRequest; - - DPRINT("BasepCreateFirstThread. hProcess: %lx\n", ProcessHandle); - - /* Create the Thread's Stack */ - BaseCreateStack(ProcessHandle, - SectionImageInfo->MaximumStackSize, - SectionImageInfo->CommittedStackSize, - &InitialTeb); - - /* Create the Thread's Context */ - BaseInitializeContext(&Context, - NtCurrentPeb(), - SectionImageInfo->TransferAddress, - InitialTeb.StackBase, - 0); - - /* Convert the thread attributes */ - ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, - lpThreadAttributes, - NULL); - - /* Create the Kernel Thread Object */ - Status = NtCreateThread(&hThread, - THREAD_ALL_ACCESS, - ObjectAttributes, - ProcessHandle, - ClientId, - &Context, - &InitialTeb, - TRUE); - if (!NT_SUCCESS(Status)) - { - return NULL; - } - - /* Fill out the request to notify CSRSS */ - CreateProcessRequest->ClientId = *ClientId; - CreateProcessRequest->ProcessHandle = ProcessHandle; - CreateProcessRequest->ThreadHandle = hThread; - CreateProcessRequest->CreationFlags = dwCreationFlags; - - /* - * For GUI applications we turn on the 2nd bit. This also allows - * us to know whether or not this is a GUI or a TUI application. - */ - if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo->SubSystemType) - { - CreateProcessRequest->ProcessHandle = (HANDLE) - ((ULONG_PTR)CreateProcessRequest->ProcessHandle | 2); - } - - /* Call CSR */ - Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, - NULL, - CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateProcess), - sizeof(BASE_CREATE_PROCESS)); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to tell CSRSS about new process: %lx\n", Status); - return NULL; - } - - /* Success */ - return hThread; -} - -/* - * Converts ANSI to Unicode Environment - */ -PVOID -WINAPI -BasepConvertUnicodeEnvironment(OUT SIZE_T* EnvSize, - IN PVOID lpEnvironment) -{ - PCHAR pcScan; - ANSI_STRING AnsiEnv; - UNICODE_STRING UnicodeEnv; - NTSTATUS Status; - - DPRINT("BasepConvertUnicodeEnvironment\n"); - - /* Scan the environment to calculate its Unicode size */ - AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment; - while (*pcScan) - { - pcScan += strlen(pcScan) + 1; - } - - /* Create our ANSI String */ - if (pcScan == (PCHAR)lpEnvironment) - { - AnsiEnv.Length = 2 * sizeof(CHAR); - } - else - { - - AnsiEnv.Length = (USHORT)((ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + sizeof(CHAR)); - } - AnsiEnv.MaximumLength = AnsiEnv.Length + 1; - - /* Allocate memory for the Unicode Environment */ - UnicodeEnv.Buffer = NULL; - *EnvSize = AnsiEnv.MaximumLength * sizeof(WCHAR); - Status = NtAllocateVirtualMemory(NtCurrentProcess(), - (PVOID)&UnicodeEnv.Buffer, - 0, - EnvSize, - MEM_COMMIT, - PAGE_READWRITE); - /* Failure */ - if (!NT_SUCCESS(Status)) - { - SetLastError(Status); - *EnvSize = 0; - return NULL; - } - - /* Use the allocated size */ - UnicodeEnv.MaximumLength = (USHORT)*EnvSize; - - /* Convert */ - RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE); - return UnicodeEnv.Buffer; -} - -/* - * Converts a Win32 Priority Class to NT - */ -ULONG -WINAPI -BasepConvertPriorityClass(IN ULONG dwCreationFlags) -{ - ULONG ReturnClass; - - if(dwCreationFlags & IDLE_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_IDLE; - } - else if(dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; - } - else if(dwCreationFlags & NORMAL_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_NORMAL; - } - else if(dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; - } - else if(dwCreationFlags & HIGH_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_HIGH; - } - else if(dwCreationFlags & REALTIME_PRIORITY_CLASS) - { - /* Check for Privilege First */ - if (BasepIsRealtimeAllowed(TRUE)) - { - ReturnClass = PROCESS_PRIORITY_CLASS_REALTIME; - } - else - { - ReturnClass = PROCESS_PRIORITY_CLASS_HIGH; - } - } - else - { - ReturnClass = PROCESS_PRIORITY_CLASS_INVALID; - } - - return ReturnClass; -} - -/* - * Duplicates a standard handle and writes it where requested. - */ -// NOTE: Code duplicated from StuffStdHandle -VOID -WINAPI -BasepDuplicateAndWriteHandle(IN HANDLE ProcessHandle, - IN HANDLE StandardHandle, - IN PHANDLE Address) -{ - NTSTATUS Status; - HANDLE DuplicatedHandle; - SIZE_T Dummy; - - DPRINT("BasepDuplicateAndWriteHandle. hProcess: %lx, Handle: %lx," - "Address: %p\n", ProcessHandle, StandardHandle, Address); - - /* Don't touch Console Handles */ - if (IsConsoleHandle(StandardHandle)) return; - - /* Duplicate the handle */ - Status = NtDuplicateObject(NtCurrentProcess(), - StandardHandle, - ProcessHandle, - &DuplicatedHandle, - 0, 0, - DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES); - if (NT_SUCCESS(Status)) - { - /* Write it */ - NtWriteVirtualMemory(ProcessHandle, - Address, - &DuplicatedHandle, - sizeof(HANDLE), - &Dummy); - } -} - BOOLEAN WINAPI BasePushProcessParameters(IN ULONG ParameterFlags, @@ -854,6 +626,8 @@ BasePushProcessParameters(IN ULONG ParameterFlags, /* Create the Parameter Block */ ProcessParameters = NULL; + DPRINT1("Image Name: %wZ Dll Path: %wZ current directory: %wZ, CmdLine: %wZ, Title: %wZ, Desktop: %wZ, Shell: %wZ, Runtime: %wZ\n", + &ImageName, &DllPath, &CurrentDirectory, &CommandLine, &Title, &Desktop, &Shell, &Runtime); Status = RtlCreateProcessParameters(&ProcessParameters, &ImageName, &DllPath, @@ -992,16 +766,16 @@ BasePushProcessParameters(IN ULONG ParameterFlags, ProcessParameters->ConsoleFlags = 1; } - /* See if the first 1MB should be reserved */ + /* Check if there's a .local file present */ if (ParameterFlags & 1) { - ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB; + ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH; } - /* See if the first 16MB should be reserved */ + /* Check if we failed to open the IFEO key */ if (ParameterFlags & 2) { - ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_16MB; + ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING; } /* Allocate memory for the parameter block */ @@ -1095,7 +869,7 @@ Quickie: if (ProcessParameters) RtlDestroyProcessParameters(ProcessParameters); return Result; FailPath: - DPRINT1("Failure to create proecss parameters: %lx\n", Status); + DPRINT1("Failure to create process parameters: %lx\n", Status); BaseSetLastNTError(Status); Result = FALSE; goto Quickie; @@ -2480,89 +2254,216 @@ ProcessIdToSessionId(IN DWORD dwProcessId, return FALSE; } + +#define AddToHandle(x,y) (x) = (HANDLE)((ULONG_PTR)(x) | (y)); +#define RemoveFromHandle(x,y) (x) = (HANDLE)((ULONG_PTR)(x) & ~(y)); +C_ASSERT(PROCESS_PRIORITY_CLASS_REALTIME == (PROCESS_PRIORITY_CLASS_HIGH + 1)); + /* * @implemented */ BOOL WINAPI -CreateProcessInternalW(HANDLE hToken, - LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation, - PHANDLE hNewToken) +CreateProcessInternalW(IN HANDLE hUserToken, + IN LPCWSTR lpApplicationName, + IN LPWSTR lpCommandLine, + IN LPSECURITY_ATTRIBUTES lpProcessAttributes, + IN LPSECURITY_ATTRIBUTES lpThreadAttributes, + IN BOOL bInheritHandles, + IN DWORD dwCreationFlags, + IN LPVOID lpEnvironment, + IN LPCWSTR lpCurrentDirectory, + IN LPSTARTUPINFOW lpStartupInfo, + IN LPPROCESS_INFORMATION lpProcessInformation, + OUT PHANDLE hNewToken) { - NTSTATUS Status; - PROCESS_PRIORITY_CLASS PriorityClass; - BOOLEAN FoundQuotes = FALSE; - BOOLEAN QuotesNeeded = FALSE; - BOOLEAN CmdLineIsAppName = FALSE; - UNICODE_STRING ApplicationName = { 0, 0, NULL }; + // + // Core variables used for creating the initial process and thread + // + SECURITY_ATTRIBUTES LocalThreadAttributes, LocalProcessAttributes; OBJECT_ATTRIBUTES LocalObjectAttributes; POBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hSection = NULL, hProcess = NULL, hThread = NULL, hDebug = NULL; - SECTION_IMAGE_INFORMATION SectionImageInfo; - LPWSTR CurrentDirectory = NULL; - LPWSTR CurrentDirectoryPart; - PROCESS_BASIC_INFORMATION ProcessBasicInfo; - STARTUPINFOW StartupInfo; - ULONG Dummy; - LPWSTR BatchCommandLine; - ULONG CmdLineLength; - UNICODE_STRING CommandLineString; - PWCHAR Extension; - LPWSTR QuotedCmdLine = NULL; - LPWSTR ScanString; - LPWSTR NullBuffer = NULL; - LPWSTR NameBuffer = NULL; - WCHAR SaveChar = 0; - ULONG RetVal; - UINT Error = 0; - BOOLEAN SearchDone = FALSE; - BOOLEAN Escape = FALSE; + SECTION_IMAGE_INFORMATION ImageInformation; + IO_STATUS_BLOCK IoStatusBlock; CLIENT_ID ClientId; - PPEB OurPeb = NtCurrentPeb(); - PPEB RemotePeb; - SIZE_T EnvSize = 0; - BOOL Ret = FALSE; + ULONG NoWindow, RegionSize, StackSize, ImageMachine, dwErrCode, Flags; + ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse; + ULONG_PTR ErrorParameters[2]; + BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege; + BOOLEAN QuerySection, SkipSaferAndAppCompat; + CONTEXT Context; + BASE_API_MESSAGE CsrMsg; + PBASE_CREATE_PROCESS CreateProcessMsg; + PCSR_CAPTURE_BUFFER CaptureBuffer; + PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState; + HANDLE DebugHandle, TokenHandle, JobHandle, KeyHandle, ThreadHandle; + HANDLE FileHandle, SectionHandle, ProcessHandle; + ULONG ResumeCount; + PROCESS_PRIORITY_CLASS PriorityClass; + NTSTATUS Status, Status1, ImageDbgStatus; + PPEB Peb, RemotePeb; + PTEB Teb; + INITIAL_TEB InitialTeb; + PVOID TibValue; + PIMAGE_NT_HEADERS NtHeaders; + STARTUPINFOW StartupInfo; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + UNICODE_STRING DebuggerString; + BOOL Result; + // + // Variables used for command-line and argument parsing + // + PCHAR pcScan; + SIZE_T n; + WCHAR TempChar; + ULONG Length, CurdirLength, CmdQuoteLength; + ULONG CmdLineLength, ResultSize; + PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory; + PWCHAR TempNull, WhiteScan, NameBuffer, SearchPath, DebuggerCmdLine; + ANSI_STRING AnsiEnv; + UNICODE_STRING UnicodeEnv, PathName; + BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName; - /* FIXME should process - * HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options - * key (see http://blogs.msdn.com/oldnewthing/archive/2005/12/19/505449.aspx) - */ + // + // Variables used for Fusion/SxS (Side-by-Side Assemblies) + // + RTL_PATH_TYPE SxsPathType, PathType; +#if _SXS_SUPPORT_ENABLED_ + PRTL_BUFFER ByteBuffer; + PRTL_UNICODE_STRING_BUFFER ThisBuffer, Buffer, SxsStaticBuffers[5]; + PRTL_UNICODE_STRING_BUFFER* BufferHead, SxsStringBuffer; + RTL_UNICODE_STRING_BUFFER SxsWin32ManifestPath, SxsNtManifestPath; + RTL_UNICODE_STRING_BUFFER SxsWin32PolicyPath, SxsNtPolicyPath; + RTL_UNICODE_STRING_BUFFER SxsWin32AssemblyDirectory; + BASE_MSG_SXS_HANDLES MappedHandles, Handles, FileHandles; + PVOID CapturedStrings[3]; + SXS_WIN32_NT_PATH_PAIR ExePathPair, ManifestPathPair, PolicyPathPair; + SXS_OVERRIDE_MANIFEST OverrideMannifest; + UNICODE_STRING FreeString, SxsNtExePath; + PWCHAR SxsConglomeratedBuffer, StaticBuffer; + ULONG ConglomeratedBufferSizeBytes, StaticBufferSize, i; +#endif + ULONG FusionFlags; - DPRINT("CreateProcessW: lpApplicationName: %S lpCommandLine: %S" - " lpEnvironment: %p lpCurrentDirectory: %S dwCreationFlags: %lx\n", - lpApplicationName, lpCommandLine, lpEnvironment, lpCurrentDirectory, - dwCreationFlags); + // + // Variables used for path conversion (and partially Fusion/SxS) + // + PWCHAR FilePart, PathBuffer, FreeBuffer; + BOOLEAN TranslationStatus; + RTL_RELATIVE_NAME_U SxsWin32RelativePath; + UNICODE_STRING PathBufferString, SxsWin32ExePath; - /* Flags we don't handle yet */ - if (dwCreationFlags & CREATE_SEPARATE_WOW_VDM) - { - DPRINT1("CREATE_SEPARATE_WOW_VDM not handled\n"); - } - if (dwCreationFlags & CREATE_SHARED_WOW_VDM) - { - DPRINT1("CREATE_SHARED_WOW_VDM not handled\n"); - } - if (dwCreationFlags & CREATE_FORCEDOS) - { - DPRINT1("CREATE_FORCEDOS not handled\n"); - } + // + // Variables used by Application Compatibility (and partially Fusion/SxS) + // + PVOID AppCompatSxsData, AppCompatData; + ULONG AppCompatSxsDataSize, AppCompatDataSize; + // + // Variables used by VDM (Virtual Dos Machine) and WOW32 (16-bit Support) + // + ULONG BinarySubType, VdmBinaryType, VdmTask, VdmReserve; + ULONG VdmUndoLevel; + BOOLEAN UseVdmReserve; + HANDLE VdmWaitObject; + ANSI_STRING VdmAnsiEnv; + UNICODE_STRING VdmString, VdmUnicodeEnv; + BOOLEAN IsWowApp; + PBASE_CHECK_VDM VdmMsg; - /* Fail on this flag, it's only valid with the WithLogonW function */ - if (dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL) - { - DPRINT1("Invalid flag used\n"); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + /* Zero out the initial core variables and handles */ + QuerySection = FALSE; + InJob = FALSE; + SkipSaferAndAppCompat = FALSE; + ParameterFlags = 0; + Flags = 0; + DebugHandle = NULL; + JobHandle = NULL; + TokenHandle = NULL; + FileHandle = NULL; + SectionHandle = NULL; + ProcessHandle = NULL; + ThreadHandle = NULL; + BaseAddress = (PVOID)1; + + /* Zero out initial SxS and Application Compatibility state */ + AppCompatData = NULL; + AppCompatDataSize = 0; + AppCompatSxsData = NULL; + AppCompatSxsDataSize = 0; + CaptureBuffer = NULL; +#if _SXS_SUPPORT_ENABLED_ + SxsConglomeratedBuffer = NULL; +#endif + FusionFlags = 0; + + /* Zero out initial parsing variables -- others are initialized later */ + DebuggerCmdLine = NULL; + PathBuffer = NULL; + SearchPath = NULL; + TempNull = 0; + FreeBuffer = NULL; + NameBuffer = NULL; + CurrentDirectory = NULL; + FilePart = NULL; + DebuggerString.Buffer = NULL; + QuotesNeeded = FALSE; + QuotedCmdLine = NULL; + + /* Zero out initial VDM state */ + VdmAnsiEnv.Buffer = NULL; + VdmUnicodeEnv.Buffer = NULL; + VdmString.Buffer = NULL; + VdmTask = 0; + VdmUndoLevel = 0; + VdmBinaryType = 0; + VdmReserve = 0; + VdmWaitObject = NULL; + UseVdmReserve = FALSE; + IsWowApp = FALSE; + + /* Set message structures */ + CreateProcessMsg = &CsrMsg.Data.CreateProcessRequest; + VdmMsg = &CsrMsg.Data.CheckVdm; + + /* Clear the more complex structures by zeroing out their entire memory */ + RtlZeroMemory(&Context, sizeof(Context)); +#if _SXS_SUPPORT_ENABLED_ + RtlZeroMemory(&FileHandles, sizeof(FileHandles)); + RtlZeroMemory(&MappedHandles, sizeof(MappedHandles)); + RtlZeroMemory(&Handles, sizeof(Handles)); +#endif + RtlZeroMemory(&CreateProcessMsg->Sxs, sizeof(CreateProcessMsg->Sxs)); + RtlZeroMemory(&LocalProcessAttributes, sizeof(LocalProcessAttributes)); + RtlZeroMemory(&LocalThreadAttributes, sizeof(LocalThreadAttributes)); + + /* Zero out output arguments as well */ + RtlZeroMemory(lpProcessInformation, sizeof(*lpProcessInformation)); + if (hNewToken) *hNewToken = NULL; + + /* Capture the special window flag */ + NoWindow = dwCreationFlags & CREATE_NO_WINDOW; + dwCreationFlags &= ~CREATE_NO_WINDOW; + +#if _SXS_SUPPORT_ENABLED_ + /* Setup the SxS static string arrays and buffers */ + SxsStaticBuffers[0] = &SxsWin32ManifestPath; + SxsStaticBuffers[1] = &SxsWin32PolicyPath; + SxsStaticBuffers[2] = &SxsWin32AssemblyDirectory; + SxsStaticBuffers[3] = &SxsNtManifestPath; + SxsStaticBuffers[4] = &SxsNtPolicyPath; + ExePathPair.Win32 = &SxsWin32ExePath; + ExePathPair.Nt = &SxsNtExePath; + ManifestPathPair.Win32 = &SxsWin32ManifestPath.String; + ManifestPathPair.Nt = &SxsNtManifestPath.String; + PolicyPathPair.Win32 = &SxsWin32PolicyPath.String; + PolicyPathPair.Nt = &SxsNtPolicyPath.String; +#endif + + DPRINT1("CreateProcessInternalW: %S %S %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags); + + /* Finally, set our TEB and PEB */ + Teb = NtCurrentTeb(); + Peb = NtCurrentPeb(); /* This combination is illegal (see MSDN) */ if ((dwCreationFlags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)) == @@ -2573,445 +2474,1349 @@ CreateProcessInternalW(HANDLE hToken, return FALSE; } - /* Another illegal combo */ - if ((dwCreationFlags & (CREATE_SEPARATE_WOW_VDM | CREATE_SHARED_WOW_VDM)) == - (CREATE_SEPARATE_WOW_VDM | CREATE_SHARED_WOW_VDM)) + /* Convert the priority class */ + if (dwCreationFlags & IDLE_PRIORITY_CLASS) { - DPRINT1("Invalid flag combo used\n"); + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE; + } + else if (dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; + } + else if (dwCreationFlags & NORMAL_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; + } + else if (dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; + } + else if (dwCreationFlags & HIGH_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; + } + else if (dwCreationFlags & REALTIME_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; + PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(0) != NULL); + } + else + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_INVALID; + } + + /* Done with the priority masks, so get rid of them */ + PriorityClass.Foreground = FALSE; + dwCreationFlags &= ~(NORMAL_PRIORITY_CLASS | + IDLE_PRIORITY_CLASS | + HIGH_PRIORITY_CLASS | + REALTIME_PRIORITY_CLASS | + BELOW_NORMAL_PRIORITY_CLASS | + ABOVE_NORMAL_PRIORITY_CLASS); + + /* You cannot request both a shared and a separate WoW VDM */ + if ((dwCreationFlags & CREATE_SEPARATE_WOW_VDM) && + (dwCreationFlags & CREATE_SHARED_WOW_VDM)) + { + /* Fail such nonsensical attempts */ + DPRINT1("Invalid WOW flags\n"); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - - if (lpCurrentDirectory) + else if (!(dwCreationFlags & CREATE_SHARED_WOW_VDM) && + (BaseStaticServerData->DefaultSeparateVDM)) { - if ((GetFileAttributesW(lpCurrentDirectory) == INVALID_FILE_ATTRIBUTES) || - !(GetFileAttributesW(lpCurrentDirectory) & FILE_ATTRIBUTE_DIRECTORY)) + /* A shared WoW VDM was not requested but system enforces separation */ + dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; + } + + /* If a shared WoW VDM is used, make sure the process isn't in a job */ + if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM) && + (NtIsProcessInJob(NtCurrentProcess(), NULL))) + { + /* Remove the shared flag and add the separate flag */ + dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) | + CREATE_SEPARATE_WOW_VDM; + } + + /* Convert the environment */ + if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + /* Scan the environment to calculate its Unicode size */ + AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment; + while ((*pcScan) || (*(pcScan + 1))) ++pcScan; + + /* Create our ANSI String */ + AnsiEnv.Length = pcScan - (PCHAR)lpEnvironment + sizeof(ANSI_NULL); + AnsiEnv.MaximumLength = AnsiEnv.Length + sizeof(ANSI_NULL); + + /* Allocate memory for the Unicode Environment */ + UnicodeEnv.Buffer = NULL; + RegionSize = AnsiEnv.MaximumLength * sizeof(WCHAR); + Status = NtAllocateVirtualMemory(NtCurrentProcess(), + (PVOID)&UnicodeEnv.Buffer, + 0, + &RegionSize, + MEM_COMMIT, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) { - SetLastError(ERROR_DIRECTORY); + /* Fail */ + BaseSetLastNTError(Status); return FALSE; } + + /* Use the allocated size and convert */ + UnicodeEnv.MaximumLength = RegionSize; + Status = RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + NtFreeVirtualMemory(NtCurrentProcess(), + (PVOID)&UnicodeEnv.Buffer, + &RegionSize, + MEM_RELEASE); + BaseSetLastNTError(Status); + return FALSE; + } + + /* Now set the Unicode environment as the environment string pointer */ + lpEnvironment = UnicodeEnv.Buffer; } - /* - * We're going to modify and mask out flags and stuff in lpStartupInfo, - * so we'll use our own local copy for that. - */ + /* Make a copy of the caller's startup info since we'll modify it */ StartupInfo = *lpStartupInfo; - /* FIXME: Use default Separate/Shared VDM Flag */ - - /* If we are inside a Job, use Separate VDM so it won't escape the Job */ - if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM)) - { - if (NtIsProcessInJob(NtCurrentProcess(), NULL)) - { - /* Remove the shared flag and add the separate flag. */ - dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) | - CREATE_SEPARATE_WOW_VDM; - } - } - - /* - * According to some sites, ShellExecuteEx uses an undocumented flag to - * send private handle data (such as HMONITOR or HICON). See: - * www.catch22.net/tuts/undoc01.asp. This implies that we can't use the - * standard handles anymore since we'd be overwriting this private data - */ + /* Check if private data is being sent on the same channel as std handles */ if ((StartupInfo.dwFlags & STARTF_USESTDHANDLES) && (StartupInfo.dwFlags & (STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))) { + /* Cannot use the std handles since we have monitor/hotkey values */ StartupInfo.dwFlags &= ~STARTF_USESTDHANDLES; } - /* Start by zeroing out the fields */ - RtlZeroMemory(lpProcessInformation, sizeof(PROCESS_INFORMATION)); - - /* Easy stuff first, convert the process priority class */ - PriorityClass.Foreground = FALSE; - PriorityClass.PriorityClass = (UCHAR)BasepConvertPriorityClass(dwCreationFlags); - - if (lpCommandLine) + /* If there's a debugger, or we have to launch cmd.exe, we go back here */ +AppNameRetry: + /* New iteration -- free any existing name buffer */ + if (NameBuffer) { - /* Search for escape sequences */ - ScanString = lpCommandLine; - while (NULL != (ScanString = wcschr(ScanString, L'^'))) - { - ScanString++; - if (*ScanString == L'\"' || *ScanString == L'^' || *ScanString == L'\\') - { - Escape = TRUE; - break; - } - } + RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); + NameBuffer = NULL; } - /* Get the application name and do all the proper formating necessary */ -GetAppName: - /* See if we have an application name (oh please let us have one!) */ + /* New iteration -- free any existing free buffer */ + if (FreeBuffer) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer); + FreeBuffer = NULL; + } + + /* New iteration -- close any existing file handle */ + if (FileHandle) + { + NtClose(FileHandle); + FileHandle = NULL; + } + + /* Set the initial parsing state. This code can loop -- don't move this! */ + dwErrCode = FALSE; + SearchRetry = TRUE; + QuotesNeeded = FALSE; + CmdLineIsAppName = FALSE; + + /* First check if we don't have an application name */ if (!lpApplicationName) { - /* The fun begins */ + /* This should be the first time we attempt creating one */ + ASSERT(NameBuffer == NULL); + + /* Allocate a buffer to hold it */ NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); - if (NameBuffer == NULL) + if (!NameBuffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; + Result = FALSE; + goto Quickie; } - /* This is all we have to work with :( */ - lpApplicationName = lpCommandLine; + /* Initialize the application name and our parsing parameters */ + lpApplicationName = TempNull = WhiteScan = lpCommandLine; - /* Initialize our friends at the beginning */ - NullBuffer = (LPWSTR)lpApplicationName; - ScanString = (LPWSTR)lpApplicationName; - - /* We will start by looking for a quote */ - if (*ScanString == L'\"') + /* Check for an initial quote*/ + if (*lpCommandLine == L'\"') { - /* That was quick */ - SearchDone = TRUE; - - /* Advance past quote */ - ScanString++; - lpApplicationName = ScanString; - - /* Find the closing quote */ - while (*ScanString) - { - if (*ScanString == L'\"' && *(ScanString - 1) != L'^') - { - /* Found it */ - NullBuffer = ScanString; - FoundQuotes = TRUE; - break; - } - - /* Keep looking */ - ScanString++; - NullBuffer = ScanString; - } - } - else - { - /* No quotes, so we'll be looking for white space */ - WhiteScan: - /* Reset the pointer */ - lpApplicationName = lpCommandLine; - - /* Find whitespace of Tab */ - while (*ScanString) + /* We found a quote, keep searching for another one */ + SearchRetry = FALSE; + WhiteScan++; + lpApplicationName = TempNull = WhiteScan; + while (*WhiteScan) { - if (*ScanString == ' ' || *ScanString == '\t') + /* Have we found the terminating quote? */ + if (*WhiteScan == L'\"') { - /* Found it */ - NullBuffer = ScanString; + /* We're done, get out of here */ + TempNull = WhiteScan; + QuotesNeeded = TRUE; break; } - /* Keep looking */ - ScanString++; - NullBuffer = ScanString; + /* Keep searching for the quote */ + WhiteScan++; + TempNull = WhiteScan; + } + } + else + { +StartScan: + /* We simply make the application name be the command line*/ + lpApplicationName = lpCommandLine; + while (*WhiteScan) + { + /* Check if it starts with a space or tab */ + if ((*WhiteScan == L' ') || (*WhiteScan == '\t')) + { + /* Break out of the search loop */ + TempNull = WhiteScan; + break; + } + + /* Keep searching for a space or tab */ + WhiteScan++; + TempNull = WhiteScan; } } - /* Set the Null Buffer */ - SaveChar = *NullBuffer; - *NullBuffer = UNICODE_NULL; + /* We have found the end of the application name, terminate it */ + TempChar = *TempNull; + *TempNull = UNICODE_NULL; - /* Do a search for the file */ - DPRINT("Ready for SearchPathW: %S\n", lpApplicationName); - RetVal = SearchPathW(NULL, + /* New iteration -- free any existing saved path */ + if (SearchPath) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath); + SearchPath = NULL; + } + + /* Now compute the final EXE path based on the name */ + SearchPath = BaseComputeProcessExePath((LPWSTR)lpApplicationName); + DPRINT1("Search Path: %S\n", SearchPath); + if (!SearchPath) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + Result = FALSE; + goto Quickie; + } + + /* And search for the executable in the search path */ + Length = SearchPathW(SearchPath, lpApplicationName, L".exe", MAX_PATH, NameBuffer, - NULL) * sizeof(WCHAR); + NULL); - /* Did it find something? */ - if (RetVal) + /* Did we find it? */ + if ((Length) && (Length < MAX_PATH)) { /* Get file attributes */ - ULONG Attributes = GetFileAttributesW(NameBuffer); - if (Attributes & FILE_ATTRIBUTE_DIRECTORY) + CurdirLength = GetFileAttributesW(NameBuffer); + if ((CurdirLength != 0xFFFFFFFF) && + (CurdirLength & FILE_ATTRIBUTE_DIRECTORY)) { - /* Give it a length of 0 to fail, this was a directory. */ - RetVal = 0; - } - else - { - /* It's a file! */ - RetVal += sizeof(WCHAR); + /* This was a directory, fail later on */ + Length = 0; } } - - /* Now check if we have a file, and if the path size is OK */ - if (!RetVal || RetVal >= (MAX_PATH * sizeof(WCHAR))) + else { - ULONG PathType; - HANDLE hFile; + /* It's a file! */ + Length++; + } - /* We failed, try to get the Path Type */ - DPRINT("SearchPathW failed. Retval: %ld\n", RetVal); + DPRINT1("Length: %lx Buffer: %S\n", Length, NameBuffer); + + /* Check if there was a failure in SearchPathW */ + if ((Length) && (Length < MAX_PATH)) + { + /* Everything looks good, restore the name */ + *TempNull = TempChar; + lpApplicationName = NameBuffer; + } + else + { + /* Check if this was a relative path, which would explain it */ PathType = RtlDetermineDosPathNameType_U(lpApplicationName); - - /* If it's not relative, try to get the error */ if (PathType != RtlPathTypeRelative) { /* This should fail, and give us a detailed LastError */ - hFile = CreateFileW(lpApplicationName, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - /* Did it actually NOT fail? */ - if (hFile != INVALID_HANDLE_VALUE) + FileHandle = CreateFileW(lpApplicationName, + GENERIC_READ, + FILE_SHARE_READ | + FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (FileHandle != INVALID_HANDLE_VALUE) { - /* Fake the error */ - CloseHandle(hFile); + /* It worked? Return a generic error */ + CloseHandle(FileHandle); + FileHandle = NULL; BaseSetLastNTError(STATUS_OBJECT_NAME_NOT_FOUND); } } else { - /* Immediately set the error */ + /* Path was absolute, which means it doesn't exist */ BaseSetLastNTError(STATUS_OBJECT_NAME_NOT_FOUND); } /* Did we already fail once? */ - if (Error) + if (dwErrCode) { - SetLastError(Error); + /* Set the error code */ + SetLastError(dwErrCode); } else { /* Not yet, cache it */ - Error = GetLastError(); + dwErrCode = GetLastError(); } /* Put back the command line */ - *NullBuffer = SaveChar; + *TempNull = TempChar; lpApplicationName = NameBuffer; - /* - * If the search isn't done and we still have cmdline - * then start over. Ex: c:\ha ha ha\haha.exe - */ - if (*ScanString && !SearchDone) + /* It's possible there's whitespace in the directory name */ + if (!(*WhiteScan) || !(SearchRetry)) { - /* Move in the buffer */ - ScanString++; - NullBuffer = ScanString; - - /* We will have to add a quote, since there is a space*/ - QuotesNeeded = TRUE; - - /* And we will also fake the fact we found one */ - FoundQuotes = TRUE; - - /* Start over */ - goto WhiteScan; + /* Not the case, give up completely */ + Result = FALSE; + goto Quickie; } - /* We totally failed */ - goto Cleanup; - } + /* There are spaces, so keep trying the next possibility */ + WhiteScan++; + TempNull = WhiteScan; - /* Put back the command line */ - *NullBuffer = SaveChar; - lpApplicationName = NameBuffer; - DPRINT("SearchPathW suceeded (%ld): %S\n", RetVal, NameBuffer); + /* We will have to add a quote, since there is a space */ + QuotesNeeded = TRUE; + goto StartScan; + } } - else if (!lpCommandLine || *lpCommandLine == UNICODE_NULL) + else if (!(lpCommandLine) || !(*lpCommandLine)) { - /* We have an app name (good!) but no command line */ + /* We don't have a command line, so just use the application name */ CmdLineIsAppName = TRUE; lpCommandLine = (LPWSTR)lpApplicationName; } - /* At this point the name has been toyed with enough to be openable */ - Status = BasepMapFile(lpApplicationName, &hSection, &ApplicationName); + /* Convert the application name to its NT path */ + TranslationStatus = RtlDosPathNameToRelativeNtPathName_U(lpApplicationName, + &PathName, + NULL, + &SxsWin32RelativePath); + if (!TranslationStatus) + { + /* Path must be invaild somehow, bail out */ + DPRINT1("Path translation for SxS failed\n"); + SetLastError(ERROR_PATH_NOT_FOUND); + Result = FALSE; + goto Quickie; + } - /* Check for failure */ + /* Setup the buffer that needs to be freed at the end */ + ASSERT(FreeBuffer == NULL); + FreeBuffer = PathName.Buffer; + + /* Check what kind of path the application is, for SxS (Fusion) purposes */ + RtlInitUnicodeString(&SxsWin32ExePath, lpApplicationName); + SxsPathType = RtlDetermineDosPathNameType_U(lpApplicationName); + if ((SxsPathType != RtlPathTypeDriveAbsolute) && + (SxsPathType != RtlPathTypeLocalDevice) && + (SxsPathType != RtlPathTypeRootLocalDevice) && + (SxsPathType != RtlPathTypeUncAbsolute)) + { + /* Relative-type path, get the full path */ + RtlInitEmptyUnicodeString(&PathBufferString, NULL, 0); + Status = RtlGetFullPathName_UstrEx(&SxsWin32ExePath, + NULL, + &PathBufferString, + NULL, + NULL, + NULL, + &SxsPathType, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Fail the rest of the create */ + RtlReleaseRelativeName(&SxsWin32RelativePath); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Use this full path as the SxS path */ + SxsWin32ExePath = PathBufferString; + PathBuffer = PathBufferString.Buffer; + PathBufferString.Buffer = NULL; + DPRINT1("SxS Path: %S\n", PathBuffer); + } + + /* Also set the .EXE path based on the path name */ +#if _SXS_SUPPORT_ENABLED_ + SxsNtExePath = PathName; +#endif + if (SxsWin32RelativePath.RelativeName.Length) + { + /* If it's relative, capture the relative name */ + PathName = SxsWin32RelativePath.RelativeName; + } + else + { + /* Otherwise, it's absolute, make sure no relative dir is used */ + SxsWin32RelativePath.ContainingDirectory = NULL; + } + + /* Now use the path name, and the root path, to try opening the app */ + DPRINT1("Path: %wZ. Dir: %lx\n", &PathName, SxsWin32RelativePath.ContainingDirectory); + InitializeObjectAttributes(&LocalObjectAttributes, + &PathName, + OBJ_CASE_INSENSITIVE, + SxsWin32RelativePath.ContainingDirectory, + NULL); + Status = NtOpenFile(&FileHandle, + SYNCHRONIZE | + FILE_READ_ATTRIBUTES | + FILE_READ_DATA | + FILE_EXECUTE, + &LocalObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT | + FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(Status)) { - /* Could be a non-PE File */ - switch (Status) + /* Try to open the app just for execute purposes instead */ + Status = NtOpenFile(&FileHandle, + SYNCHRONIZE | FILE_EXECUTE, + &LocalObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT | + FILE_NON_DIRECTORY_FILE); + } + + /* Cleanup in preparation for failure or success */ + RtlReleaseRelativeName(&SxsWin32RelativePath); + if (!NT_SUCCESS(Status)) + { + /* Failure path, try to understand why */ + DPRINT1("Open file failed: %lx\n", Status); + if (RtlIsDosDeviceName_U(lpApplicationName)) { - /* Check if the Kernel tells us it's not even valid MZ */ - case STATUS_INVALID_IMAGE_NE_FORMAT: - case STATUS_INVALID_IMAGE_PROTECT: - case STATUS_INVALID_IMAGE_NOT_MZ: - -#if 0 - /* If it's a DOS app, use VDM */ - if ((BasepCheckDosApp(&ApplicationName))) - { - DPRINT1("Launching VDM...\n"); - RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); - RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); - return CreateProcessW(L"ntvdm.exe", - (LPWSTR)((ULONG_PTR)lpApplicationName), /* FIXME: Buffer must be writable!!! */ - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - &StartupInfo, - lpProcessInformation); - } -#endif - /* It's a batch file */ - Extension = &ApplicationName.Buffer[ApplicationName.Length / - sizeof(WCHAR) - 4]; - - /* Make sure the extensions are correct */ - if (_wcsnicmp(Extension, L".bat", 4) && _wcsnicmp(Extension, L".cmd", 4)) - { - SetLastError(ERROR_BAD_EXE_FORMAT); - return FALSE; - } - - /* Calculate the length of the command line */ - CmdLineLength = wcslen(CMD_STRING) + wcslen(lpCommandLine) + 1; - - /* If we found quotes, then add them into the length size */ - if (CmdLineIsAppName || FoundQuotes) CmdLineLength += 2; - CmdLineLength *= sizeof(WCHAR); - - /* Allocate space for the new command line */ - BatchCommandLine = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - CmdLineLength); - if (BatchCommandLine == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; - } - - /* Build it */ - wcscpy(BatchCommandLine, CMD_STRING); - if (CmdLineIsAppName || FoundQuotes) - { - wcscat(BatchCommandLine, L"\""); - } - wcscat(BatchCommandLine, lpCommandLine); - if (CmdLineIsAppName || FoundQuotes) - { - wcscat(BatchCommandLine, L"\""); - } - - /* Create it as a Unicode String */ - RtlInitUnicodeString(&CommandLineString, BatchCommandLine); - - /* Set the command line to this */ - lpCommandLine = CommandLineString.Buffer; - lpApplicationName = NULL; - - /* Free memory */ - RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); - ApplicationName.Buffer = NULL; - goto GetAppName; - break; - - case STATUS_INVALID_IMAGE_WIN_16: - - /* It's a Win16 Image, use VDM */ - DPRINT1("Launching VDM...\n"); - RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); - RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); - return CreateProcessW(L"ntvdm.exe", - (LPWSTR)((ULONG_PTR)lpApplicationName), /* FIXME: Buffer must be writable!!! */ - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - &StartupInfo, - lpProcessInformation); - - case STATUS_OBJECT_NAME_NOT_FOUND: - case STATUS_OBJECT_PATH_NOT_FOUND: - BaseSetLastNTError(Status); - goto Cleanup; - - default: - /* Invalid Image Type */ - SetLastError(ERROR_BAD_EXE_FORMAT); - goto Cleanup; + /* If a device is being executed, return this special error code */ + SetLastError(ERROR_BAD_DEVICE); + Result = FALSE; + goto Quickie; + } + else + { + /* Otherwise return the converted NT error code */ + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; } } - /* Use our desktop if we didn't get any */ + /* Did the caller specify a desktop? */ if (!StartupInfo.lpDesktop) { - StartupInfo.lpDesktop = OurPeb->ProcessParameters->DesktopInfo.Buffer; + /* Use the one from the current process */ + StartupInfo.lpDesktop = Peb->ProcessParameters->DesktopInfo.Buffer; } - /* FIXME: Check if Application is allowed to run */ - - /* FIXME: Allow CREATE_SEPARATE only for WOW Apps, once we have that. */ - - /* Get some information about the executable */ - Status = NtQuerySection(hSection, - SectionImageInformation, - &SectionImageInfo, - sizeof(SectionImageInfo), - NULL); - if(!NT_SUCCESS(Status)) + /* Create a section for this file */ + Status = NtCreateSection(&SectionHandle, + SECTION_ALL_ACCESS, + NULL, + NULL, + PAGE_EXECUTE, + SEC_IMAGE, + FileHandle); + DPRINT1("Section status: %lx\n", Status); + if (NT_SUCCESS(Status)) { - DPRINT1("Unable to get SectionImageInformation, status 0x%x\n", Status); - BaseSetLastNTError(Status); - goto Cleanup; + /* Are we running on Windows Embedded, Datacenter, Blade or Starter? */ + if (SharedUserData->SuiteMask & (VER_SUITE_EMBEDDEDNT | + VER_SUITE_DATACENTER | + VER_SUITE_PERSONAL | + VER_SUITE_BLADE)) + { + /* These SKUs do not allow running certain applications */ + Status = BasepCheckWebBladeHashes(FileHandle); + if (Status == STATUS_ACCESS_DENIED) + { + /* And this is one of them! */ + DPRINT1("Invalid Blade hashes!\n"); + SetLastError(ERROR_ACCESS_DISABLED_WEBBLADE); + Result = FALSE; + goto Quickie; + } + + /* Did we get some other failure? */ + if (!NT_SUCCESS(Status)) + { + /* If we couldn't check the hashes, assume nefariousness */ + DPRINT1("Tampered Blade hashes!\n"); + SetLastError(ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER); + Result = FALSE; + goto Quickie; + } + } + + /* Now do Winsafer, etc, checks */ + Status = BasepIsProcessAllowed((LPWSTR)lpApplicationName); + if (!NT_SUCCESS(Status)) + { + /* Fail if we're not allowed to launch the process */ + DPRINT1("Process not allowed to launch: %lx\n", Status); + BaseSetLastNTError(Status); + if (SectionHandle) + { + NtClose(SectionHandle); + SectionHandle = NULL; + } + Result = FALSE; + goto Quickie; + } + + /* Is a DOS VDM being forced, but we already have a WOW32 instance ready? */ + if ((dwCreationFlags & CREATE_FORCEDOS) && + (BaseStaticServerData->IsWowTaskReady)) + { + /* This request can't be satisifeed, instead, a separate VDM is needed */ + dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM); + dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; + + /* Set a failure code, ask for VDM reservation */ + Status = STATUS_INVALID_IMAGE_WIN_16; + UseVdmReserve = TRUE; + + /* Close the current handle */ + NtClose(SectionHandle); + SectionHandle = NULL; + + /* Don't query the section later */ + QuerySection = FALSE; + } } - /* Don't execute DLLs */ - if (SectionImageInfo.ImageCharacteristics & IMAGE_FILE_DLL) + /* Did we already do these checks? */ + if (!SkipSaferAndAppCompat) { - DPRINT1("Can't execute a DLL\n"); + /* Is everything OK so far, OR do we have an non-MZ, non-DOS app? */ + if ((NT_SUCCESS(Status)) || + ((Status == STATUS_INVALID_IMAGE_NOT_MZ) && + !(BaseIsDosApplication(&PathName, Status)))) + { + /* Clear the machine type in case of failure */ + ImageMachine = 0; + + /* Clean any app compat data that may have accumulated */ + BasepFreeAppCompatData(AppCompatData, AppCompatSxsData); + AppCompatData = NULL; + AppCompatSxsData = NULL; + + /* Do we have a section? */ + if (SectionHandle) + { + /* Have we already queried it? */ + if (QuerySection) + { + /* Nothing to do */ + Status = STATUS_SUCCESS; + } + else + { + /* Get some information about the executable */ + Status = NtQuerySection(SectionHandle, + SectionImageInformation, + &ImageInformation, + sizeof(ImageInformation), + NULL); + } + + /* Do we have section information now? */ + if (NT_SUCCESS(Status)) + { + /* Don't ask for it again, save the machine type */ + QuerySection = TRUE; + ImageMachine = ImageInformation.Machine; + } + } + + /* Is there a reason/Shim we shouldn't run this application? */ + Status = BasepCheckBadapp(FileHandle, + FreeBuffer, + lpEnvironment, + ImageMachine, + &AppCompatData, + &AppCompatDataSize, + &AppCompatSxsData, + &AppCompatSxsDataSize, + &FusionFlags); + if (!NT_SUCCESS(Status)) + { + /* This is usually the status we get back */ + DPRINT1("App compat launch failure: %lx\n", Status); + if (Status == STATUS_ACCESS_DENIED) + { + /* Convert it to something more Win32-specific */ + SetLastError(ERROR_CANCELLED); + } + else + { + /* Some other error */ + BaseSetLastNTError(Status); + } + + /* Did we have a section? */ + if (SectionHandle) + { + /* Clean it up */ + NtClose(SectionHandle); + SectionHandle = NULL; + } + + /* Fail the call */ + Result = FALSE; + goto Quickie; + } + } + } + + //ASSERT((dwFusionFlags & ~SXS_APPCOMPACT_FLAG_APP_RUNNING_SAFEMODE) == 0); + + /* Have we already done, and do we need to do, SRP (WinSafer) checks? */ + if (!(SkipSaferAndAppCompat) && + ~(dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL)) + { + /* Assume yes */ + SaferNeeded = TRUE; + switch (Status) + { + case STATUS_INVALID_IMAGE_NE_FORMAT: + case STATUS_INVALID_IMAGE_PROTECT: + case STATUS_INVALID_IMAGE_WIN_16: + case STATUS_FILE_IS_OFFLINE: + /* For all DOS, 16-bit, OS/2 images, we do*/ + break; + + case STATUS_INVALID_IMAGE_NOT_MZ: + /* For invalid files, we don't, unless it's a .BAT file */ + if (BaseIsDosApplication(&PathName, Status)) break; + + default: + /* Any other error codes we also don't */ + if (!NT_SUCCESS(Status)) + { + SaferNeeded = FALSE; + } + + /* But for success, we do */ + break; + } + + /* Okay, so what did the checks above result in? */ + if (SaferNeeded) + { + /* We have to call into the WinSafer library and actually check */ + Status = BasepCheckWinSaferRestrictions(hUserToken, + (LPWSTR)lpApplicationName, + FileHandle, + &InJob, + &TokenHandle, + &JobHandle); + if (Status == 0xFFFFFFFF) + { + /* Back in 2003, they didn't have an NTSTATUS for this... */ + DPRINT1("WinSafer blocking process launch\n"); + SetLastError(ERROR_ACCESS_DISABLED_BY_POLICY); + Result = FALSE; + goto Quickie; + } + + /* Other status codes are not-Safer related, just convert them */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error checking WinSafer: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + } + } + + /* The last step is to figure out why the section object was not created */ + switch (Status) + { + case STATUS_INVALID_IMAGE_WIN_16: + /* 16-bit binary. Should we use WOW or does the caller force VDM? */ + if (!(dwCreationFlags & CREATE_FORCEDOS)) + { + /* Remember that we're launching WOW */ + IsWowApp = TRUE; + + /* Create the VDM environment, it's valid for WOW too */ + Result = BaseCreateVDMEnvironment(lpEnvironment, + &VdmAnsiEnv, + &VdmUnicodeEnv); + if (!Result) + { + DPRINT1("VDM environment for WOW app failed\n"); + goto Quickie; + } + + /* We're going to try this twice, so do a loop */ + while (TRUE) + { + /* Pick which kind of WOW mode we want to run in */ + VdmBinaryType = (dwCreationFlags & + CREATE_SEPARATE_WOW_VDM) ? + BINARY_TYPE_WOW : BINARY_TYPE_SEPARATE_WOW; + + /* Get all the VDM settings and current status */ + Status = BaseCheckVDM(VdmBinaryType, + lpApplicationName, + lpCommandLine, + lpCurrentDirectory, + &VdmAnsiEnv, + (PCSR_API_MESSAGE)VdmMsg, + &VdmTask, + dwCreationFlags, + &StartupInfo, + hUserToken); + + /* If it worked, no need to try again */ + if (NT_SUCCESS(Status)) break; + + /* Check if it's disallowed or if it's our second time */ + BaseSetLastNTError(Status); + if ((Status == STATUS_VDM_DISALLOWED) || + (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) || + (GetLastError() == ERROR_ACCESS_DENIED)) + { + /* Fail the call -- we won't try again */ + DPRINT1("VDM message failure for WOW: %lx\n", Status); + Result = FALSE; + goto Quickie; + } + + /* Try one more time, but with a separate WOW instance */ + dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; + } + + /* Check which VDM state we're currently in */ + switch (VdmMsg->VDMState & (VDM_NOT_LOADED | + VDM_NOT_READY | + VDM_READY)) + { + case VDM_NOT_LOADED: + /* VDM is not fully loaded, so not that much to undo */ + VdmUndoLevel = VDM_UNDO_PARTIAL; + + /* Reset VDM reserve if needed */ + if (UseVdmReserve) VdmReserve = 1; + + /* Get the required parameters and names for launch */ + Result = BaseGetVdmConfigInfo(lpCommandLine, + VdmTask, + VdmBinaryType, + &VdmString, + &VdmReserve); + if (!Result) + { + DPRINT1("VDM Configuration failed for WOW\n"); + BaseSetLastNTError(Status); + goto Quickie; + } + + /* Update the command-line with the VDM one instead */ + lpCommandLine = VdmString.Buffer; + lpApplicationName = NULL; + + /* We don't want a console, detachment, nor a window */ + dwCreationFlags |= CREATE_NO_WINDOW; + dwCreationFlags &= ~(CREATE_NEW_CONSOLE | DETACHED_PROCESS); + + /* Force feedback on */ + StartupInfo.dwFlags |= STARTF_FORCEONFEEDBACK; + break; + + + case VDM_READY: + /* VDM is ready, so we have to undo everything */ + VdmUndoLevel = VDM_UNDO_REUSE; + + /* Check if CSRSS wants us to wait on VDM */ + VdmWaitObject = VdmMsg->WaitObjectForParent; + break; + + case VDM_NOT_READY: + /* Something is wrong with VDM, we'll fail the call */ + DPRINT1("VDM is not ready for WOW\n"); + SetLastError(ERROR_NOT_READY); + Result = FALSE; + goto Quickie; + + default: + break; + } + + /* Since to get NULL, we allocate from 0x1, account for this */ + VdmReserve--; + + /* This implies VDM is ready, so skip everything else */ + if (VdmWaitObject) goto VdmShortCircuit; + + /* Don't inherit handles since we're doing VDM now */ + bInheritHandles = FALSE; + + /* Had the user passed in environment? If so, destroy it */ + if ((lpEnvironment) && + !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + RtlDestroyEnvironment(lpEnvironment); + } + + /* We've already done all these checks, don't do them again */ + SkipSaferAndAppCompat = TRUE; + goto AppNameRetry; + } + + // There is no break here on purpose, so FORCEDOS drops down! + case STATUS_INVALID_IMAGE_PROTECT: + case STATUS_INVALID_IMAGE_NOT_MZ: + case STATUS_INVALID_IMAGE_NE_FORMAT: + /* We're launching an executable application */ + BinarySubType = BINARY_TYPE_EXE; + + /* We can drop here from other "cases" above too, so check */ + if ((Status == STATUS_INVALID_IMAGE_PROTECT) || + (Status == STATUS_INVALID_IMAGE_NE_FORMAT) || + (BinarySubType = BaseIsDosApplication(&PathName, Status))) + { + /* We're launching a DOS application */ + VdmBinaryType = BINARY_TYPE_DOS; + + /* Based on the caller environment, create a VDM one */ + Result = BaseCreateVDMEnvironment(lpEnvironment, + &VdmAnsiEnv, + &VdmUnicodeEnv); + if (!Result) + { + DPRINT1("VDM environment for DOS failed\n"); + goto Quickie; + } + + /* Check the current state of the VDM subsystem */ + Status = BaseCheckVDM(VdmBinaryType | BinarySubType, + lpApplicationName, + lpCommandLine, + lpCurrentDirectory, + &VdmAnsiEnv, + (PCSR_API_MESSAGE)VdmMsg, + &VdmTask, + dwCreationFlags, + &StartupInfo, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed to inquire about VDM, fail the call */ + DPRINT1("VDM message failure for DOS: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + }; + + /* Handle possible VDM states */ + switch (VdmMsg->VDMState & (VDM_NOT_LOADED | + VDM_NOT_READY | + VDM_READY)) + { + case VDM_NOT_LOADED: + /* If VDM is not loaded, we'll do a partial undo */ + VdmUndoLevel = VDM_UNDO_PARTIAL; + + /* A VDM process can't also be detached, so fail */ + if (dwCreationFlags & DETACHED_PROCESS) + { + DPRINT1("Detached process but no VDM, not allowed\n"); + SetLastError(ERROR_ACCESS_DENIED); + return FALSE; + } + + /* Get the required parameters and names for launch */ + Result = BaseGetVdmConfigInfo(lpCommandLine, + VdmTask, + VdmBinaryType, + &VdmString, + &VdmReserve); + if (!Result) + { + DPRINT1("VDM Configuration failed for DOS\n"); + BaseSetLastNTError(Status); + goto Quickie; + } + + /* Update the command-line to launch VDM instead */ + lpCommandLine = VdmString.Buffer; + lpApplicationName = NULL; + break; + + case VDM_READY: + /* VDM is ready, so we have to undo everything */ + VdmUndoLevel = VDM_UNDO_REUSE; + + /* Check if CSRSS wants us to wait on VDM */ + VdmWaitObject = VdmMsg->WaitObjectForParent; + break; + + case VDM_NOT_READY: + /* Something is wrong with VDM, we'll fail the call */ + DPRINT1("VDM is not ready for DOS\n"); + SetLastError(ERROR_NOT_READY); + Result = FALSE; + goto Quickie; + + default: + break; + } + + /* Since to get NULL, we allocate from 0x1, account for this */ + VdmReserve--; + + /* This implies VDM is ready, so skip everything else */ + if (VdmWaitObject) goto VdmShortCircuit; + + /* Don't inherit handles since we're doing VDM now */ + bInheritHandles = FALSE; + + /* Had the user passed in environment? If so, destroy it */ + if ((lpEnvironment) && + !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + RtlDestroyEnvironment(lpEnvironment); + } + + /* Use our VDM Unicode environment instead */ + lpEnvironment = VdmUnicodeEnv.Buffer; + } + else + { + /* It's a batch file, get the extension */ + ExtBuffer = &PathName.Buffer[PathName.Length / sizeof(WCHAR) - 4]; + + /* Make sure the extensions are correct */ + if ((PathName.Length < (4 * sizeof(WCHAR))) || + ((_wcsnicmp(ExtBuffer, L".bat", 4)) && + (_wcsnicmp(ExtBuffer, L".cmd", 4)))) + { + DPRINT1("Invalid EXE, and not a batch or script file\n"); + SetLastError(ERROR_BAD_EXE_FORMAT); + Result = FALSE; + goto Quickie; + } + + /* Check if we need to account for quotes around the path */ + CmdQuoteLength = CmdLineIsAppName || QuotesNeeded; + if (!CmdLineIsAppName) + { + if (QuotesNeeded) CmdQuoteLength++; + } + else + { + CmdQuoteLength++; + } + + /* Calculate the length of the command line */ + CmdLineLength = wcslen(lpCommandLine); + CmdLineLength += wcslen(CMD_STRING); + CmdLineLength += CmdQuoteLength + sizeof(ANSI_NULL); + CmdLineLength *= sizeof(WCHAR); + + /* Allocate space for the new command line */ + AnsiCmdCommand = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + CmdLineLength); + if (!AnsiCmdCommand) + { + BaseSetLastNTError(STATUS_NO_MEMORY); + Result = FALSE; + goto Quickie; + } + + /* Build it */ + wcscpy(AnsiCmdCommand, CMD_STRING); + if ((CmdLineIsAppName) || (QuotesNeeded)) + { + wcscat(AnsiCmdCommand, L"\""); + } + wcscat(AnsiCmdCommand, lpCommandLine); + if ((CmdLineIsAppName) || (QuotesNeeded)) + { + wcscat(AnsiCmdCommand, L"\""); + } + + /* Create it as a Unicode String */ + RtlInitUnicodeString(&DebuggerString, AnsiCmdCommand); + + /* Set the command line to this */ + lpCommandLine = DebuggerString.Buffer; + lpApplicationName = NULL; + DPRINT1("Retrying with: %S\n", lpCommandLine); + } + + /* We've already done all these checks, don't do them again */ + SkipSaferAndAppCompat = TRUE; + goto AppNameRetry; + + case STATUS_INVALID_IMAGE_WIN_64: + /* 64-bit binaries are not allowed to run on 32-bit ReactOS */ + DPRINT1("64-bit binary, failing\n"); + SetLastError(ERROR_EXE_MACHINE_TYPE_MISMATCH); + Result = FALSE; + goto Quickie; + + case STATUS_FILE_IS_OFFLINE: + /* Set the correct last error for this */ + DPRINT1("File is offline, failing\n"); + SetLastError(ERROR_FILE_OFFLINE); + break; + + default: + /* Any other error, convert it to a generic Win32 error */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create section: %lx\n", Status); + SetLastError(ERROR_BAD_EXE_FORMAT); + Result = FALSE; + goto Quickie; + } + + /* Otherwise, this must be success */ + ASSERT(Status == STATUS_SUCCESS); + break; + } + + /* Is this not a WOW application, but a WOW32 VDM was requested for it? */ + if (!(IsWowApp) && (dwCreationFlags & CREATE_SEPARATE_WOW_VDM)) + { + /* Ignore the nonsensical request */ + dwCreationFlags &= ~CREATE_SEPARATE_WOW_VDM; + } + + /* Did we already check information for the section? */ + if (!QuerySection) + { + /* Get some information about the executable */ + Status = NtQuerySection(SectionHandle, + SectionImageInformation, + &ImageInformation, + sizeof(ImageInformation), + NULL); + if (!NT_SUCCESS(Status)) + { + /* We failed, bail out */ + DPRINT1("Section query failed\n"); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Don't check this later */ + QuerySection = TRUE; + } + + /* Check if this was linked as a DLL */ + if (ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL) + { + /* These aren't valid images to try to execute! */ + DPRINT1("Trying to launch a DLL, failing\n"); SetLastError(ERROR_BAD_EXE_FORMAT); - goto Cleanup; + Result = FALSE; + goto Quickie; } - /* FIXME: Check for Debugger */ + /* Don't let callers pass in this flag -- we'll only get it from IFRO */ + Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES; - /* FIXME: Check if Machine Type and SubSys Version Match */ + /* Clear the IFEO-missing flag, before we know for sure... */ + ParameterFlags &= ~2; - /* We don't support POSIX or anything else for now */ - if (IMAGE_SUBSYSTEM_WINDOWS_GUI != SectionImageInfo.SubSystemType && - IMAGE_SUBSYSTEM_WINDOWS_CUI != SectionImageInfo.SubSystemType) + /* If the process is being debugged, only read IFEO if the PEB says so */ + if (!(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) || + (NtCurrentPeb()->ReadImageFileExecOptions)) { - DPRINT1("Invalid subsystem %d\n", SectionImageInfo.SubSystemType); - /* - * Despite the name of the error code suggests, it corresponds to the - * well-known "The %1 application cannot be run in Win32 mode" message. - */ - SetLastError(ERROR_CHILD_NOT_COMPLETE); - goto Cleanup; + /* Let's do this! Attempt to open IFEO */ + Status1 = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle); + if (!NT_SUCCESS(Status1)) + { + /* We failed, set the flag so we store this in the parameters */ + if (Status1 == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2; + } + else + { + /* Was this our first time going through this path? */ + if (!DebuggerCmdLine) + { + /* Allocate a buffer for the debugger path */ + DebuggerCmdLine = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + MAX_PATH * sizeof(WCHAR)); + if (!DebuggerCmdLine) + { + /* Close IFEO on failure */ + Status1 = NtClose(KeyHandle); + ASSERT(NT_SUCCESS(Status1)); + + /* Fail the call */ + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + Result = FALSE; + goto Quickie; + } + } + + /* Now query for the debugger */ + Status1 = LdrQueryImageFileKeyOption(KeyHandle, + L"Debugger", + REG_SZ, + DebuggerCmdLine, + MAX_PATH * sizeof(WCHAR), + &ResultSize); + if (!(NT_SUCCESS(Status1)) || + (ResultSize < sizeof(WCHAR)) || + (DebuggerCmdLine[0] == UNICODE_NULL)) + { + /* If it's not there, or too small, or invalid, ignore it */ + RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine); + DebuggerCmdLine = NULL; + } + + /* Also query if we should map with large pages */ + Status1 = LdrQueryImageFileKeyOption(KeyHandle, + L"UseLargePages", + REG_DWORD, + &UseLargePages, + sizeof(UseLargePages), + NULL); + if ((NT_SUCCESS(Status1)) && (UseLargePages)) + { + /* Do it! This is the only way this flag can be set */ + Flags |= PROCESS_CREATE_FLAGS_LARGE_PAGES; + } + + /* We're done with IFEO, can close it now */ + Status1 = NtClose(KeyHandle); + ASSERT(NT_SUCCESS(Status1)); + } } - if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo.SubSystemType) + /* Make sure the image was compiled for this processor */ + if ((ImageInformation.Machine < SharedUserData->ImageNumberLow) || + (ImageInformation.Machine > SharedUserData->ImageNumberHigh)) { - /* Do not create a console for GUI applications */ - dwCreationFlags &= ~CREATE_NEW_CONSOLE; - dwCreationFlags |= DETACHED_PROCESS; + /* It was not -- raise a hard error */ + ErrorResponse = ResponseOk; + ErrorParameters[0] = (ULONG_PTR)&PathName; + NtRaiseHardError(STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE, + 1, + 1, + ErrorParameters, + OptionOk, + &ErrorResponse); + if (Peb->ImageSubsystemMajorVersion <= 3) + { + /* If it's really old, return this error */ + SetLastError(ERROR_BAD_EXE_FORMAT); + } + else + { + /* Otherwise, return a more modern error */ + SetLastError(ERROR_EXE_MACHINE_TYPE_MISMATCH); + } + + /* Go to the failure path */ + DPRINT1("Invalid image architecture: %lx\n", ImageInformation.Machine); + Result = FALSE; + goto Quickie; + } + + /* Check if this isn't a Windows image */ + if ((ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_GUI) && + (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI)) + { + /* Get rid of section-related information since we'll retry */ + NtClose(SectionHandle); + SectionHandle = NULL; + QuerySection = FALSE; + + /* The only other non-Windows image type we support here is POSIX */ + if (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_POSIX_CUI) + { + /* Bail out if it's something else */ + SetLastError(ERROR_CHILD_NOT_COMPLETE); + Result = FALSE; + goto Quickie; + } + + /* Now build the command-line to have posix launch this image */ + Result = BuildSubSysCommandLine(L"POSIX /P ", + lpApplicationName, + lpCommandLine, + &DebuggerString); + if (!Result) + { + /* Bail out if that failed */ + DPRINT1("Subsystem command line failed\n"); + goto Quickie; + } + + /* And re-try launching the process, with the new command-line now */ + lpCommandLine = DebuggerString.Buffer; + lpApplicationName = NULL; + + /* We've already done all these checks, don't do them again */ + SkipSaferAndAppCompat = TRUE; + DPRINT1("Retrying with: %S\n", lpCommandLine); + goto AppNameRetry; + } + + /* Was this image built for a version of Windows whose images we can run? */ + Result = BasepIsImageVersionOk(ImageInformation.SubSystemMajorVersion, + ImageInformation.SubSystemMinorVersion); + if (!Result) + { + /* It was not, bail out */ + DPRINT1("Invalid subsystem version: %d.%d\n", + ImageInformation.SubSystemMajorVersion, + ImageInformation.SubSystemMinorVersion); + SetLastError(ERROR_BAD_EXE_FORMAT); + goto Quickie; + } + + /* Check if there is a debugger associated with the application */ + if (DebuggerCmdLine) + { + /* Get the length of the command line */ + n = wcslen(lpCommandLine); + if (!n) + { + /* There's no command line, use the application name instead */ + lpCommandLine = (LPWSTR)lpApplicationName; + n = wcslen(lpCommandLine); + } + + /* Protect against overflow */ + if (n > UNICODE_STRING_MAX_CHARS) + { + BaseSetLastNTError(STATUS_NAME_TOO_LONG); + Result = FALSE; + goto Quickie; + } + + /* Now add the length of the debugger command-line */ + n += wcslen(DebuggerCmdLine); + + /* Again make sure we don't overflow */ + if (n > UNICODE_STRING_MAX_CHARS) + { + BaseSetLastNTError(STATUS_NAME_TOO_LONG); + Result = FALSE; + goto Quickie; + } + + /* Account for the quotes and space between the two */ + n += ((sizeof('""') * 2) + sizeof(' ')); + + /* Convert to bytes, and make sure we don't overflow */ + n *= sizeof(WCHAR); + if (n > UNICODE_STRING_MAX_BYTES) + { + BaseSetLastNTError(STATUS_NAME_TOO_LONG); + Result = FALSE; + goto Quickie; + } + + /* Allocate space for the string */ + DebuggerString.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, n); + if (!DebuggerString.Buffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + Result = FALSE; + goto Quickie; + } + + /* Set the length */ + RtlInitEmptyUnicodeString(&DebuggerString, + DebuggerString.Buffer, + n); + + /* Now perform the command line creation */ + ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, + DebuggerCmdLine); + ASSERT(NT_SUCCESS(ImageDbgStatus)); + ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, L" "); + ASSERT(NT_SUCCESS(ImageDbgStatus)); + ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, lpCommandLine); + ASSERT(NT_SUCCESS(ImageDbgStatus)); + + /* Make sure it all looks nice */ + DbgPrint("BASE: Calling debugger with '%wZ'\n", &DebuggerString); + + /* Update the command line and application name */ + lpCommandLine = DebuggerString.Buffer; + lpApplicationName = NULL; + + /* Close all temporary state */ + NtClose(SectionHandle); + SectionHandle = NULL; + QuerySection = FALSE; + + /* Free all temporary memory */ + RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); + NameBuffer = NULL; + RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer); + FreeBuffer = NULL; + RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine); + DebuggerCmdLine = NULL; + DPRINT1("Retrying with: %S\n", lpCommandLine); + goto AppNameRetry; } /* Initialize the process object attributes */ ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, - lpProcessAttributes, - NULL); + lpProcessAttributes, + NULL); + if ((hUserToken) && (lpProcessAttributes)) + { + /* Auggment them with information from the user */ + + LocalProcessAttributes = *lpProcessAttributes; + LocalProcessAttributes.lpSecurityDescriptor = NULL; + ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, + &LocalProcessAttributes, + NULL); + } /* Check if we're going to be debugged */ if (dwCreationFlags & DEBUG_PROCESS) { - /* FIXME: Set process flag */ + /* Set process flag */ + Flags |= PROCESS_CREATE_FLAGS_BREAKAWAY; } /* Check if we're going to be debugged */ @@ -3023,275 +3828,749 @@ GetAppName: { DPRINT1("Failed to connect to DbgUI!\n"); BaseSetLastNTError(Status); - goto Cleanup; + Result = FALSE; + goto Quickie; } /* Get the debug object */ - hDebug = DbgUiGetThreadDebugObject(); + DebugHandle = DbgUiGetThreadDebugObject(); /* Check if only this process will be debugged */ if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS) { /* Set process flag */ - hDebug = (HANDLE)((ULONG_PTR)hDebug | 0x1); + Flags |= PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT; } } - /* Create the Process */ - Status = NtCreateProcess(&hProcess, - PROCESS_ALL_ACCESS, - ObjectAttributes, - NtCurrentProcess(), - (BOOLEAN)bInheritHandles, - hSection, - hDebug, - NULL); - if (!NT_SUCCESS(Status)) + /* Set inherit flag */ + if (bInheritHandles) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES; + + /* Check if the process should be created with large pages */ + HavePrivilege = FALSE; + PrivilegeState = NULL; + if (Flags & PROCESS_CREATE_FLAGS_LARGE_PAGES) { - DPRINT1("Unable to create process, status 0x%x\n", Status); - BaseSetLastNTError(Status); - goto Cleanup; + /* Acquire the required privilege so that the kernel won't fail the call */ + PrivilegeValue = SE_LOCK_MEMORY_PRIVILEGE; + Status = RtlAcquirePrivilege(&PrivilegeValue, TRUE, FALSE, &PrivilegeState); + if (NT_SUCCESS(Status)) + { + /* Remember to release it later */ + HavePrivilege = TRUE; + } } - if (PriorityClass.PriorityClass != PROCESS_PRIORITY_CLASS_INVALID) + /* Save the current TIB value since kernel overwrites it to store PEB */ + TibValue = Teb->NtTib.ArbitraryUserPointer; + + /* Tell the kernel to create the process */ + Status = NtCreateProcessEx(&ProcessHandle, + PROCESS_ALL_ACCESS, + ObjectAttributes, + NtCurrentProcess(), + Flags, + SectionHandle, + DebugHandle, + NULL, + InJob); + + /* Load the PEB address from the hacky location where the kernel stores it */ + RemotePeb = Teb->NtTib.ArbitraryUserPointer; + + /* And restore the old TIB value */ + Teb->NtTib.ArbitraryUserPointer = TibValue; + + /* Release the large page privilege if we had acquired it */ + if (HavePrivilege) RtlReleasePrivilege(PrivilegeState); + + /* And now check if the kernel failed to create the process */ + if (!NT_SUCCESS(Status)) { - /* Set new class */ - Status = NtSetInformationProcess(hProcess, + /* Go to failure path */ + DPRINT1("Failed to create process: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Check if there is a priority class to set */ + if (PriorityClass.PriorityClass) + { + /* Reset current privilege state */ + RealTimePrivilegeState = NULL; + + /* Is realtime priority being requested? */ + if (PriorityClass.PriorityClass == REALTIME_PRIORITY_CLASS) + { + /* Check if the caller has real-time access, and enable it if so */ + RealTimePrivilegeState = BasepIsRealtimeAllowed(TRUE); + } + + /* Set the new priority class and release the privilege */ + Status = NtSetInformationProcess(ProcessHandle, ProcessPriorityClass, &PriorityClass, sizeof(PROCESS_PRIORITY_CLASS)); - if(!NT_SUCCESS(Status)) + if (RealTimePrivilegeState) RtlReleasePrivilege(RealTimePrivilegeState); + + /* Check if we failed to set the priority class */ + if (!NT_SUCCESS(Status)) { - DPRINT1("Unable to set new process priority, status 0x%x\n", Status); + /* Bail out on failure */ + DPRINT1("Failed to set priority class: %lx\n", Status); BaseSetLastNTError(Status); - goto Cleanup; + Result = FALSE; + goto Quickie; } } - /* Set Error Mode */ + /* Check if the caller wants the default error mode */ if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE) { - ULONG ErrorMode = SEM_FAILCRITICALERRORS; - NtSetInformationProcess(hProcess, + /* Set Error Mode to only fail on critical errors */ + HardErrorMode = SEM_FAILCRITICALERRORS; + NtSetInformationProcess(ProcessHandle, ProcessDefaultHardErrorMode, - &ErrorMode, + &HardErrorMode, sizeof(ULONG)); } - /* Convert the directory to a full path */ - if (lpCurrentDirectory) + /* Check if this was a VDM binary */ + if (VdmBinaryType) { - /* Allocate a buffer */ - CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - (MAX_PATH + 1) * sizeof(WCHAR)); - if (CurrentDirectory == NULL) + /* Update VDM by telling it the process has now been created */ + VdmWaitObject = ProcessHandle; + Result = BaseUpdateVDMEntry(VdmEntryUpdateProcess, + &VdmWaitObject, + VdmTask, + VdmBinaryType); { - DPRINT1("Cannot allocate memory for directory name\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; + /* Bail out on failure */ + DPRINT1("Failed to update VDM with wait object\n"); + VdmWaitObject = NULL; + goto Quickie; } - /* Get the length */ - if (GetFullPathNameW(lpCurrentDirectory, - MAX_PATH, - CurrentDirectory, - &CurrentDirectoryPart) > MAX_PATH) + /* At this point, a failure means VDM has to undo all the state */ + VdmUndoLevel |= VDM_UNDO_FULL; + } + + /* Check if VDM needed reserved low-memory */ + if (VdmReserve) + { + /* Reserve the requested allocation */ + Status = NtAllocateVirtualMemory(ProcessHandle, + &BaseAddress, + 0, + &VdmReserve, + MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + if (!NT_SUCCESS(Status)) { - DPRINT1("Directory name too long\n"); + /* Bail out on failure */ + DPRINT1("Failed to reserved memory for VDM: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + } + + /* Check if we've already queried information on the section */ + if (!QuerySection) + { + /* We haven't, so get some information about the executable */ + Status = NtQuerySection(SectionHandle, + SectionImageInformation, + &ImageInformation, + sizeof(ImageInformation), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Bail out on failure */ + DPRINT1("Failed to query section: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* If we encounter a restart, don't re-query this information again */ + QuerySection = TRUE; + } + + /* Do we need to apply SxS to this image? */ + if (!(ImageInformation.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_ISOLATION)) + { + /* Too bad, we don't support this yet */ + DPRINT1("Image should receive SxS Fusion Isolation\n"); + } + + /* There's some SxS flag that we need to set if fusion flags have 1 set */ + if (FusionFlags & 1) CreateProcessMsg->Sxs.Flags |= 0x10; + + /* Check if we have a current directory */ + if (lpCurrentDirectory) + { + /* Allocate a buffer so we can keep a Unicode copy */ + DPRINT1("Current directory: %S\n", lpCurrentDirectory); + CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + (MAX_PATH * sizeof(WCHAR)) + + sizeof(UNICODE_NULL)); + if (!CurrentDirectory) + { + /* Bail out if this failed */ + BaseSetLastNTError(STATUS_NO_MEMORY); + Result = FALSE; + goto Quickie; + } + + /* Get the length in Unicode */ + Length = GetFullPathNameW(lpCurrentDirectory, + MAX_PATH, + CurrentDirectory, + &FilePart); + if (Length > MAX_PATH) + { + /* The directory is too long, so bail out */ SetLastError(ERROR_DIRECTORY); - goto Cleanup; + Result = FALSE; + goto Quickie; + } + + /* Make sure the directory is actually valid */ + CurdirLength = GetFileAttributesW(CurrentDirectory); + if ((CurdirLength == 0xffffffff) || + !(CurdirLength & FILE_ATTRIBUTE_DIRECTORY)) + { + /* It isn't, so bail out */ + DPRINT1("Current directory is invalid\n"); + SetLastError(ERROR_DIRECTORY); + Result = FALSE; + goto Quickie; } } /* Insert quotes if needed */ - if (QuotesNeeded || CmdLineIsAppName) + if ((QuotesNeeded) || (CmdLineIsAppName)) { - /* Allocate a buffer */ + /* Allocate our buffer, plus enough space for quotes and a NULL */ QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(), 0, - (wcslen(lpCommandLine) + 2 + 1) * - sizeof(WCHAR)); - if (QuotedCmdLine == NULL) + wcslen(lpCommandLine) * sizeof(WCHAR) + + 2 * sizeof(L'\"') + sizeof(UNICODE_NULL)); + if (QuotedCmdLine) { - DPRINT1("Cannot allocate memory for quoted command line\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; - } + /* Copy the first quote */ + wcscpy(QuotedCmdLine, L"\""); - /* Copy the first quote */ - wcscpy(QuotedCmdLine, L"\""); - - /* Save a null char */ - if (QuotesNeeded) - { - SaveChar = *NullBuffer; - *NullBuffer = UNICODE_NULL; - } - - /* Add the command line and the finishing quote */ - wcscat(QuotedCmdLine, lpCommandLine); - wcscat(QuotedCmdLine, L"\""); - - /* Add the null char */ - if (QuotesNeeded) - { - *NullBuffer = SaveChar; - wcscat(QuotedCmdLine, NullBuffer); - } - - DPRINT("Quoted CmdLine: %S\n", QuotedCmdLine); - } - - if (Escape) - { - if (QuotedCmdLine == NULL) - { - QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - (wcslen(lpCommandLine) + 1) * sizeof(WCHAR)); - if (QuotedCmdLine == NULL) + /* Save the current null-character */ + if (QuotesNeeded) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; + TempChar = *TempNull; + *TempNull = UNICODE_NULL; } - wcscpy(QuotedCmdLine, lpCommandLine); - } - ScanString = QuotedCmdLine; - while (NULL != (ScanString = wcschr(ScanString, L'^'))) - { - ScanString++; - if (*ScanString == L'\"' || *ScanString == L'^' || *ScanString == L'\\') + /* Copy the command line and the final quote */ + wcscat(QuotedCmdLine, lpCommandLine); + wcscat(QuotedCmdLine, L"\""); + + /* Copy the null-char back */ + if (QuotesNeeded) { - memmove(ScanString-1, ScanString, wcslen(ScanString) * sizeof(WCHAR) + sizeof(WCHAR)); + *TempNull = TempChar; + wcscat(QuotedCmdLine, TempNull); } } + else + { + /* We can't put quotes around the thing, so try it anyway */ + if (QuotesNeeded) QuotesNeeded = FALSE; + if (CmdLineIsAppName) CmdLineIsAppName = FALSE; + } } - /* Get the Process Information */ - Status = NtQueryInformationProcess(hProcess, - ProcessBasicInformation, - &ProcessBasicInfo, - sizeof(ProcessBasicInfo), - NULL); + /* Reserve the first 1MB if needed */ + if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1; - /* Convert the environment */ - if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */ + Result = BasePushProcessParameters(ParameterFlags, + ProcessHandle, + RemotePeb, + lpApplicationName, + CurrentDirectory, + ((QuotesNeeded) || (CmdLineIsAppName)) ? + QuotedCmdLine : lpCommandLine, + lpEnvironment, + &StartupInfo, + dwCreationFlags | NoWindow, + bInheritHandles, + IsWowApp ? IMAGE_SUBSYSTEM_WINDOWS_GUI: 0, + AppCompatData, + AppCompatDataSize); + if (!Result) { - lpEnvironment = BasepConvertUnicodeEnvironment(&EnvSize, lpEnvironment); - if (!lpEnvironment) goto Cleanup; + /* The remote process would have an undefined state, so fail the call */ + DPRINT1("BasePushProcessParameters failed\n"); + goto Quickie; } - /* Create Process Environment */ - RemotePeb = ProcessBasicInfo.PebBaseAddress; - Ret = BasePushProcessParameters(0, - hProcess, - RemotePeb, - (LPWSTR)lpApplicationName, - CurrentDirectory, - (QuotesNeeded || CmdLineIsAppName || Escape) ? - QuotedCmdLine : lpCommandLine, - lpEnvironment, - &StartupInfo, - dwCreationFlags, - bInheritHandles, - 0, - NULL, - 0); - if (!Ret) goto Cleanup; + /* Free the VDM command line string as it's no longer needed */ + RtlFreeUnicodeString(&VdmString); + VdmString.Buffer = NULL; - /* Cleanup Environment */ - if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + /* Non-VDM console applications usually inherit handles unless specified */ + if (!(VdmBinaryType) && + !(bInheritHandles) && + !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) && + !(dwCreationFlags & (CREATE_NO_WINDOW | + CREATE_NEW_CONSOLE | + DETACHED_PROCESS)) && + (ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI)) { - RtlDestroyEnvironment(lpEnvironment); - } - - /* Close the section */ - NtClose(hSection); - hSection = NULL; - - /* Duplicate the handles if needed */ - if (!bInheritHandles && !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) && - SectionImageInfo.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI) - { - PRTL_USER_PROCESS_PARAMETERS RemoteParameters; - /* Get the remote parameters */ - Status = NtReadVirtualMemory(hProcess, + Status = NtReadVirtualMemory(ProcessHandle, &RemotePeb->ProcessParameters, - &RemoteParameters, - sizeof(PVOID), + &ProcessParameters, + sizeof(PRTL_USER_PROCESS_PARAMETERS), NULL); + if (NT_SUCCESS(Status)) + { + /* Duplicate standard input unless it's a console handle */ + if (!IsConsoleHandle(Peb->ProcessParameters->StandardInput)) + { + StuffStdHandle(&ProcessParameters->StandardInput, + ProcessHandle, + Peb->ProcessParameters->StandardInput); + } + + /* Duplicate standard output unless it's a console handle */ + if (!IsConsoleHandle(Peb->ProcessParameters->StandardOutput)) + { + StuffStdHandle(&ProcessParameters->StandardOutput, + ProcessHandle, + Peb->ProcessParameters->StandardOutput); + } + + /* Duplicate standard error unless it's a console handle */ + if (!IsConsoleHandle(Peb->ProcessParameters->StandardError)) + { + StuffStdHandle(&ProcessParameters->StandardError, + ProcessHandle, + Peb->ProcessParameters->StandardError); + } + } + } + + /* Create the Thread's Stack */ + StackSize = max(256 * 1024, ImageInformation.MaximumStackSize); + Status = BaseCreateStack(ProcessHandle, + ImageInformation.CommittedStackSize, + StackSize, + &InitialTeb); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Creating the thread stack failed: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Create the Thread's Context */ + BaseInitializeContext(&Context, + Peb, + ImageInformation.TransferAddress, + InitialTeb.StackBase, + 0); + + /* Convert the thread attributes */ + ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, + lpThreadAttributes, + NULL); + if ((hUserToken) && (lpThreadAttributes)) + { + /* If the caller specified a user token, zero the security descriptor */ + LocalThreadAttributes = *lpThreadAttributes; + LocalThreadAttributes.lpSecurityDescriptor = NULL; + ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, + &LocalThreadAttributes, + NULL); + } + + /* Create the Kernel Thread Object */ + Status = NtCreateThread(&ThreadHandle, + THREAD_ALL_ACCESS, + ObjectAttributes, + ProcessHandle, + &ClientId, + &Context, + &InitialTeb, + TRUE); + if (!NT_SUCCESS(Status)) + { + /* A process is not allowed to exist without a main thread, so fail */ + DPRINT1("Creating the main thread failed: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Begin filling out the CSRSS message, first with our IDs and handles */ + CreateProcessMsg->ProcessHandle = ProcessHandle; + CreateProcessMsg->ThreadHandle = ThreadHandle; + CreateProcessMsg->ClientId = ClientId; + + /* Write the remote PEB address and clear it locally, we no longer use it */ + CreateProcessMsg->PebAddressNative = RemotePeb; + CreateProcessMsg->PebAddressWow64 = (ULONG)RemotePeb; + RemotePeb = NULL; + + /* Now check what kind of architecture this image was made for */ + switch (ImageInformation.Machine) + { + /* IA32, IA64 and AMD64 are supported in Server 2003 */ + case IMAGE_FILE_MACHINE_I386: + CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; + break; + case IMAGE_FILE_MACHINE_IA64: + CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64; + break; + case IMAGE_FILE_MACHINE_AMD64: + CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; + break; + + /* Anything else results in image unknown -- but no failure */ + default: + DbgPrint("kernel32: No mapping for ImageInformation.Machine == %04x\n", + ImageInformation.Machine); + CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN; + break; + } + + /* Write the input creation flags except any debugger-related flags */ + CreateProcessMsg->CreationFlags = dwCreationFlags & + ~(DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS); + + /* CSRSS needs to know if this is a GUI app or not */ + if ((ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI) || + (IsWowApp)) + { + /* Some flag sent to CSRSS, not sure for what purpose */ + AddToHandle(CreateProcessMsg->ProcessHandle, 2); + + /* Also check if the parent is also a GUI process */ + NtHeaders = RtlImageNtHeader(GetModuleHandle(NULL)); + if ((NtHeaders) && + (NtHeaders->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)) + { + /* Let it know that it should dislay the hourglass mouse cursor */ + AddToHandle(CreateProcessMsg->ProcessHandle, 1); + } + } + + /* For all apps, if this flag is on, the hourglass mouse cursor is shown */ + if (StartupInfo.dwFlags & STARTF_FORCEONFEEDBACK) + { + AddToHandle(CreateProcessMsg->ProcessHandle, 1); + } + + /* Likewise, the opposite holds as well */ + if (StartupInfo.dwFlags & STARTF_FORCEOFFFEEDBACK) + { + RemoveFromHandle(CreateProcessMsg->ProcessHandle, 1); + } + + /* Also store which kind of VDM app (if any) this is */ + CreateProcessMsg->VdmBinaryType = VdmBinaryType; + + /* And if it really is a VDM app... */ + if (VdmBinaryType) + { + /* Store the task ID and VDM console handle */ + CreateProcessMsg->hVDM = VdmTask ? 0 : Peb->ProcessParameters->ConsoleHandle; + CreateProcessMsg->VdmTask = VdmTask; + } + else if (VdmReserve) + { + /* Extended VDM, set a flag */ + CreateProcessMsg->VdmBinaryType |= BINARY_TYPE_WOW_EX; + } + + /* Check if there's side-by-side assembly data associated with the process */ + if (CreateProcessMsg->Sxs.Flags) + { + /* This should not happen in ReactOS yet */ + DPRINT1("This is an SxS Message -- should not happen yet\n"); + BaseSetLastNTError(STATUS_NOT_IMPLEMENTED); + NtTerminateProcess(ProcessHandle, STATUS_NOT_IMPLEMENTED); + Result = FALSE; + goto Quickie; + } + + /* We are finally ready to call CSRSS to tell it about our new process! */ + CsrClientCallServer((PCSR_API_MESSAGE)&CsrMsg, + CaptureBuffer, + CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, + BasepCreateProcess), + sizeof(*CreateProcessMsg)); + + /* CSRSS has returned, free the capture buffer now if we had one */ + if (CaptureBuffer) + { + CsrFreeCaptureBuffer(CaptureBuffer); + CaptureBuffer = NULL; + } + + /* Check if CSRSS failed to accept ownership of the new Windows process */ + if (!NT_SUCCESS(CsrMsg.Status)) + { + /* Terminate the process and enter failure path with the CSRSS status */ + DPRINT1("Failed to tell csrss about new process\n"); + BaseSetLastNTError(CsrMsg.Status); + NtTerminateProcess(ProcessHandle, CsrMsg.Status); + Result = FALSE; + goto Quickie; + } + + /* Check if we have a token due to Authz/Safer, not passed by the user */ + if ((TokenHandle) && !(hUserToken)) + { + /* Replace the process and/or thread token with the one from Safer */ + Status = BasepReplaceProcessThreadTokens(TokenHandle, + ProcessHandle, + ThreadHandle); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to read memory\n"); - goto Cleanup; + /* If this failed, kill the process and enter the failure path */ + DPRINT1("Failed to update process token: %lx\n", Status); + NtTerminateProcess(ProcessHandle, Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; } - - /* Duplicate and write the handles */ - BasepDuplicateAndWriteHandle(hProcess, - OurPeb->ProcessParameters->StandardInput, - &RemoteParameters->StandardInput); - BasepDuplicateAndWriteHandle(hProcess, - OurPeb->ProcessParameters->StandardOutput, - &RemoteParameters->StandardOutput); - BasepDuplicateAndWriteHandle(hProcess, - OurPeb->ProcessParameters->StandardError, - &RemoteParameters->StandardError); } - /* Create the first thread */ - DPRINT("Creating thread for process (EntryPoint = 0x%p)\n", - SectionImageInfo.TransferAddress); - hThread = BasepCreateFirstThread(hProcess, - lpThreadAttributes, - &SectionImageInfo, - &ClientId, - dwCreationFlags); - - if (hThread == NULL) + /* Check if a job was associated with this process */ + if (JobHandle) { - DPRINT1("Could not create Initial Thread\n"); - /* FIXME - set last error code */ - goto Cleanup; + /* Bind the process and job together now */ + Status = NtAssignProcessToJobObject(JobHandle, ProcessHandle); + if (!NT_SUCCESS(Status)) + { + /* Kill the process and enter the failure path if binding failed */ + DPRINT1("Failed to assign process to job: %lx\n", Status); + NtTerminateProcess(ProcessHandle, STATUS_ACCESS_DENIED); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } } + /* Finally, resume the thread to actually get the process started */ if (!(dwCreationFlags & CREATE_SUSPENDED)) { - NtResumeThread(hThread, &Dummy); + NtResumeThread(ThreadHandle, &ResumeCount); } - /* Return Data */ - lpProcessInformation->dwProcessId = (DWORD)ClientId.UniqueProcess; - lpProcessInformation->dwThreadId = (DWORD)ClientId.UniqueThread; - lpProcessInformation->hProcess = hProcess; - lpProcessInformation->hThread = hThread; - DPRINT("hThread[%p]: %p inside hProcess[%p]: %p\n", hThread, - ClientId.UniqueThread, ClientId.UniqueProcess, hProcess); - hProcess = hThread = NULL; - Ret = TRUE; +VdmShortCircuit: + /* We made it this far, meaning we have a fully created process and thread */ + Result = TRUE; -Cleanup: - /* De-allocate heap strings */ - if (NameBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); - if (ApplicationName.Buffer) - RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); - if (CurrentDirectory) RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory); - if (QuotedCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine); + /* Anyone doing a VDM undo should now undo everything, since we are done */ + if (VdmUndoLevel) VdmUndoLevel |= VDM_UNDO_COMPLETED; - /* Kill any handles still alive */ - if (hSection) NtClose(hSection); - if (hThread) + /* Having a VDM wait object implies this must be a VDM process */ + if (VdmWaitObject) { - /* We don't know any more details than this */ - NtTerminateProcess(hProcess, STATUS_UNSUCCESSFUL); - NtClose(hThread); - } - if (hProcess) NtClose(hProcess); + /* Check if it's a 16-bit separate WOW process */ + if (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) + { + /* OR-in the special flag to indicate this, and return to caller */ + AddToHandle(VdmWaitObject, 2); + lpProcessInformation->hProcess = VdmWaitObject; - /* Return Success */ - return Ret; + /* Check if this was a re-used VDM */ + if (VdmUndoLevel & VDM_UNDO_REUSE) + { + /* No Client ID should be returned in this case */ + ClientId.UniqueProcess = 0; + ClientId.UniqueThread = 0; + } + } + else + { + /* OR-in the special flag to indicate this is not a separate VDM */ + AddToHandle(VdmWaitObject, 1); + + /* Return handle to the caller */ + lpProcessInformation->hProcess = VdmWaitObject; + } + + /* Close the original process handle, since it's not needed for VDM */ + if (ProcessHandle) NtClose(ProcessHandle); + } + else + { + /* This is a regular process, so return the real process handle */ + lpProcessInformation->hProcess = ProcessHandle; + } + + /* Return the rest of the process information based on what we have so far */ + lpProcessInformation->hThread = ThreadHandle; + lpProcessInformation->dwProcessId = HandleToUlong(ClientId.UniqueProcess); + lpProcessInformation->dwThreadId = HandleToUlong(ClientId.UniqueThread); + + /* NULL these out here so we know to treat this as a success scenario */ + ProcessHandle = NULL; + ThreadHandle = NULL; + +Quickie: + /* Free the debugger command line if one was allocated */ + if (DebuggerCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine); + + /* Check if an SxS full path as queried */ + if (PathBuffer) + { + /* Reinitialize the executable path */ + RtlInitEmptyUnicodeString(&SxsWin32ExePath, NULL, 0); + SxsWin32ExePath.Length = 0; + + /* Free the path buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer); + } + +#if _SXS_SUPPORT_ENABLED_ + /* Check if this was a non-VDM process */ + if (!VdmBinaryType) + { + /* Then it must've had SxS data, so close the handles used for it */ + BasepSxsCloseHandles(&Handles); + BasepSxsCloseHandles(&FileHandles); + + /* Check if we built SxS byte buffers for this create process request */ + if (SxsConglomeratedBuffer) + { + /* Loop all of them */ + for (i = 0; i < 5; i++) + { + /* Check if this one was allocated */ + ThisBuffer = SxsStaticBuffers[i]; + if (ThisBuffer) + { + /* Get the underlying RTL_BUFFER structure */ + ByteBuffer = &ThisBuffer->ByteBuffer; + if ((ThisBuffer != (PVOID)-8) && (ByteBuffer->Buffer)) + { + /* Check if it was dynamic */ + if (ByteBuffer->Buffer != ByteBuffer->StaticBuffer) + { + /* Free it from the heap */ + FreeString.Buffer = (PWCHAR)ByteBuffer->Buffer; + RtlFreeUnicodeString(&FreeString); + } + + /* Reset the buffer to its static data */ + ByteBuffer->Buffer = ByteBuffer->StaticBuffer; + ByteBuffer->Size = ByteBuffer->StaticSize; + } + + /* Reset the string to the static buffer */ + RtlInitEmptyUnicodeString(&ThisBuffer->String, + (PWCHAR)ByteBuffer->StaticBuffer, + ByteBuffer->StaticSize); + if (ThisBuffer->String.Buffer) + { + /* Also NULL-terminate it */ + *ThisBuffer->String.Buffer = UNICODE_NULL; + } + } + } + } + } +#endif + /* Check if an environment was passed in */ + if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + /* Destroy it */ + RtlDestroyEnvironment(lpEnvironment); + + /* If this was the VDM environment too, clear that as well */ + if (VdmUnicodeEnv.Buffer == lpEnvironment) VdmUnicodeEnv.Buffer = NULL; + lpEnvironment = NULL; + } + + /* Unconditionally free all the name parsing buffers we always allocate */ + RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine); + RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); + RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory); + RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer); + + /* Close open file/section handles */ + if (FileHandle) NtClose(FileHandle); + if (SectionHandle) NtClose(SectionHandle); + + /* If we have a thread handle, this was a failure path */ + if (ThreadHandle) + { + /* So kill the process and close the thread handle */ + NtTerminateProcess(ProcessHandle, 0); + NtClose(ThreadHandle); + } + + /* If we have a process handle, this was a failure path, so close it */ + if (ProcessHandle) NtClose(ProcessHandle); + + /* Thread/process handles, if any, are now processed. Now close this one. */ + if (JobHandle) NtClose(JobHandle); + + /* Check if we had created a token */ + if (TokenHandle) + { + /* And if the user asked for one */ + if (hUserToken) + { + /* Then return it */ + *hNewToken = TokenHandle; + } + else + { + /* User didn't want it, so we used it temporarily -- close it */ + NtClose(TokenHandle); + } + } + + /* Free any temporary app compatibility data, it's no longer needed */ + BasepFreeAppCompatData(AppCompatData, AppCompatSxsData); + + /* Free a few strings. The API takes care of these possibly being NULL */ + RtlFreeUnicodeString(&VdmString); + RtlFreeUnicodeString(&DebuggerString); + + /* Check if we had built any sort of VDM environment */ + if ((VdmAnsiEnv.Buffer) || (VdmUnicodeEnv.Buffer)) + { + /* Free it */ + BaseDestroyVDMEnvironment(&VdmAnsiEnv, &VdmUnicodeEnv); + } + + /* Check if this was any kind of VDM application that we ended up creating */ + if ((VdmUndoLevel) && (!(VdmUndoLevel & VDM_UNDO_COMPLETED))) + { + /* Send an undo */ + BaseUpdateVDMEntry(VdmEntryUndo, + (PHANDLE)&VdmTask, + VdmUndoLevel, + VdmBinaryType); + + /* And close whatever VDM handle we were using for notifications */ + if (VdmWaitObject) NtClose(VdmWaitObject); + } + + /* Check if we ended up here with an allocated search path, and free it */ + if (SearchPath) RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath); + + /* Finally, return the API's result */ + return Result; } /* @@ -3311,7 +4590,7 @@ CreateProcessW(LPCWSTR lpApplicationName, LPPROCESS_INFORMATION lpProcessInformation) { /* Call the internal (but exported) version */ - return CreateProcessInternalW(0, + return CreateProcessInternalW(NULL, lpApplicationName, lpCommandLine, lpProcessAttributes, @@ -3479,7 +4758,7 @@ CreateProcessA(LPCSTR lpApplicationName, LPPROCESS_INFORMATION lpProcessInformation) { /* Call the internal (but exported) version */ - return CreateProcessInternalA(0, + return CreateProcessInternalA(NULL, lpApplicationName, lpCommandLine, lpProcessAttributes, diff --git a/reactos/dll/win32/kernel32/client/vdm.c b/reactos/dll/win32/kernel32/client/vdm.c index bfbde543b6e..69a701079db 100644 --- a/reactos/dll/win32/kernel32/client/vdm.c +++ b/reactos/dll/win32/kernel32/client/vdm.c @@ -73,7 +73,8 @@ BaseCheckVDM(IN ULONG BinaryType, IN PCSR_API_MESSAGE ApiMessage, IN OUT PULONG iTask, IN DWORD CreationFlags, - IN LPSTARTUPINFOW StartupInfo) + IN LPSTARTUPINFOW StartupInfo, + IN HANDLE hUserToken OPTIONAL) { /* This is not supported */ UNIMPLEMENTED; diff --git a/reactos/dll/win32/kernel32/include/kernel32.h b/reactos/dll/win32/kernel32/include/kernel32.h index 9a203d75a39..9e5e6659dcb 100644 --- a/reactos/dll/win32/kernel32/include/kernel32.h +++ b/reactos/dll/win32/kernel32/include/kernel32.h @@ -410,13 +410,13 @@ BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry, typedef NTSTATUS (NTAPI *PBASEP_APPCERT_PLUGIN_FUNC)( - IN PCHAR ApplicationName, + IN LPWSTR ApplicationName, IN ULONG CertFlag ); typedef NTSTATUS (NTAPI *PBASEP_APPCERT_EMBEDDED_FUNC)( - IN PCHAR ApplicationName + IN LPWSTR ApplicationName ); typedef NTSTATUS @@ -491,6 +491,22 @@ BaseCheckForVDM( OUT LPDWORD ExitCode ); +BOOL +WINAPI +BaseCheckVDM( + IN ULONG BinaryType, + IN PCWCH ApplicationName, + IN PCWCH CommandLine, + IN PCWCH CurrentDirectory, + IN PANSI_STRING AnsiEnvironment, + IN PCSR_API_MESSAGE ApiMessage, + IN OUT PULONG iTask, + IN DWORD CreationFlags, + IN LPSTARTUPINFOW StartupInfo, + IN HANDLE hUserToken OPTIONAL +); + + /* FIXME: This is EXPORTED! It should go in an external kernel32.h header */ VOID WINAPI @@ -498,3 +514,14 @@ BasepFreeAppCompatData( IN PVOID AppCompatData, IN PVOID AppCompatSxsData ); + +NTSTATUS +WINAPI +BasepCheckWinSaferRestrictions( + IN HANDLE UserToken, + IN LPWSTR ApplicationName, + IN HANDLE FileHandle, + OUT PBOOLEAN InJob, + OUT PHANDLE NewToken, + OUT PHANDLE JobHandle +); From 53d4f6c6a30964687d3fc710f4233a3b1efe2b22 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 4 Aug 2013 17:32:38 +0000 Subject: [PATCH 02/25] [KERNEL32] [FORMATTING]: Separate volume.c into disk.c, volume.c, and mountpt.c. Format function headers appropriately. No code change. svn path=/trunk/; revision=59638 --- reactos/dll/win32/kernel32/CMakeLists.txt | 2 + reactos/dll/win32/kernel32/client/file/disk.c | 424 ++++++++ .../dll/win32/kernel32/client/file/mntpoint.c | 394 +++++++ .../dll/win32/kernel32/client/file/volume.c | 986 ++---------------- 4 files changed, 904 insertions(+), 902 deletions(-) create mode 100644 reactos/dll/win32/kernel32/client/file/disk.c create mode 100644 reactos/dll/win32/kernel32/client/file/mntpoint.c diff --git a/reactos/dll/win32/kernel32/CMakeLists.txt b/reactos/dll/win32/kernel32/CMakeLists.txt index caf39abae86..fc2cd0a6a2b 100644 --- a/reactos/dll/win32/kernel32/CMakeLists.txt +++ b/reactos/dll/win32/kernel32/CMakeLists.txt @@ -47,6 +47,7 @@ list(APPEND SOURCE client/file/delete.c client/file/deviceio.c client/file/dir.c + client/file/disk.c client/file/fileinfo.c client/file/filemap.c client/file/filename.c @@ -57,6 +58,7 @@ list(APPEND SOURCE client/file/lock.c client/file/mailslot.c client/file/move.c + client/file/mntpoint.c client/file/npipe.c client/file/rw.c client/file/tape.c diff --git a/reactos/dll/win32/kernel32/client/file/disk.c b/reactos/dll/win32/kernel32/client/file/disk.c new file mode 100644 index 00000000000..c54ebe97e67 --- /dev/null +++ b/reactos/dll/win32/kernel32/client/file/disk.c @@ -0,0 +1,424 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/file/disk.c + * PURPOSE: Disk and Drive functions + * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) + * Erik Bos, Alexandre Julliard : + * GetLogicalDriveStringsA, + * GetLogicalDriveStringsW, GetLogicalDrives + * UPDATE HISTORY: + * Created 01/11/98 + */ +//WINE copyright notice: +/* + * DOS drives handling functions + * + * Copyright 1993 Erik Bos + * Copyright 1996 Alexandre Julliard + */ + +#include +#define NDEBUG +#include +DEBUG_CHANNEL(kernel32file); + +#define MAX_DOS_DRIVES 26 +HANDLE WINAPI InternalOpenDirW(IN LPCWSTR DirName, IN BOOLEAN Write); + +/* + * @implemented + */ +/* Synced to Wine-2008/12/28 */ +DWORD +WINAPI +GetLogicalDriveStringsA(IN DWORD nBufferLength, + IN LPSTR lpBuffer) +{ + DWORD drive, count; + DWORD dwDriveMap; + LPSTR p; + + dwDriveMap = GetLogicalDrives(); + + for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++) + { + if (dwDriveMap & (1< nBufferLength) return ((count * 4) + 1); + + p = lpBuffer; + + for (drive = 0; drive < MAX_DOS_DRIVES; drive++) + if (dwDriveMap & (1< nBufferLength) return ((count * 4) + 1); + + p = lpBuffer; + for (drive = 0; drive < MAX_DOS_DRIVES; drive++) + if (dwDriveMap & (1<QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.CallerAvailableAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfBytes != NULL) + { + lpTotalNumberOfBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.TotalAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfFreeBytes != NULL) + { + lpTotalNumberOfFreeBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.ActualAvailableAllocationUnits.QuadPart; + } + + return TRUE; + } + } + + Status = NtQueryVolumeInformationFile(hFile, + &IoStatusBlock, + &FsInfo.FsSize, + sizeof(FsInfo.FsSize), + FileFsSizeInformation); + + /* Close the handle before returning data + to avoid a handle leak in case of a fault! */ + CloseHandle(hFile); + + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError (Status); + return FALSE; + } + + BytesPerCluster.QuadPart = + FsInfo.FsSize.BytesPerSector * FsInfo.FsSize.SectorsPerAllocationUnit; + + if (lpFreeBytesAvailableToCaller) + { + lpFreeBytesAvailableToCaller->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfBytes) + { + lpTotalNumberOfBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsSize.TotalAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfFreeBytes) + { + lpTotalNumberOfFreeBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; + } + + return TRUE; +} + +/* + * @implemented + */ +UINT +WINAPI +GetDriveTypeA(IN LPCSTR lpRootPathName) +{ + PWCHAR RootPathNameW; + + if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE))) + return DRIVE_UNKNOWN; + + return GetDriveTypeW(RootPathNameW); +} + +/* + * @implemented + */ +UINT +WINAPI +GetDriveTypeW(IN LPCWSTR lpRootPathName) +{ + FILE_FS_DEVICE_INFORMATION FileFsDevice; + IO_STATUS_BLOCK IoStatusBlock; + + HANDLE hFile; + NTSTATUS errCode; + + hFile = InternalOpenDirW(lpRootPathName, FALSE); + if (hFile == INVALID_HANDLE_VALUE) + { + return DRIVE_NO_ROOT_DIR; /* According to WINE regression tests */ + } + + errCode = NtQueryVolumeInformationFile (hFile, + &IoStatusBlock, + &FileFsDevice, + sizeof(FILE_FS_DEVICE_INFORMATION), + FileFsDeviceInformation); + if (!NT_SUCCESS(errCode)) + { + CloseHandle(hFile); + BaseSetLastNTError (errCode); + return 0; + } + CloseHandle(hFile); + + switch (FileFsDevice.DeviceType) + { + case FILE_DEVICE_CD_ROM: + case FILE_DEVICE_CD_ROM_FILE_SYSTEM: + return DRIVE_CDROM; + case FILE_DEVICE_VIRTUAL_DISK: + return DRIVE_RAMDISK; + case FILE_DEVICE_NETWORK_FILE_SYSTEM: + return DRIVE_REMOTE; + case FILE_DEVICE_DISK: + case FILE_DEVICE_DISK_FILE_SYSTEM: + if (FileFsDevice.Characteristics & FILE_REMOTE_DEVICE) + return DRIVE_REMOTE; + if (FileFsDevice.Characteristics & FILE_REMOVABLE_MEDIA) + return DRIVE_REMOVABLE; + return DRIVE_FIXED; + } + + ERR("Returning DRIVE_UNKNOWN for device type %d\n", FileFsDevice.DeviceType); + + return DRIVE_UNKNOWN; +} + +/* EOF */ diff --git a/reactos/dll/win32/kernel32/client/file/mntpoint.c b/reactos/dll/win32/kernel32/client/file/mntpoint.c new file mode 100644 index 00000000000..af0ae94df2f --- /dev/null +++ b/reactos/dll/win32/kernel32/client/file/mntpoint.c @@ -0,0 +1,394 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/file/mntpoint.c + * PURPOSE: File volume mount point functions + * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) + * Erik Bos, Alexandre Julliard : + * GetLogicalDriveStringsA, + * GetLogicalDriveStringsW, GetLogicalDrives + * UPDATE HISTORY: + * Created 01/11/98 + */ +//WINE copyright notice: +/* + * DOS drives handling functions + * + * Copyright 1993 Erik Bos + * Copyright 1996 Alexandre Julliard + */ + +#include +#define NDEBUG +#include +DEBUG_CHANNEL(kernel32file); + +/** + * @name GetVolumeNameForVolumeMountPointW + * @implemented + * + * Return an unique volume name for a drive root or mount point. + * + * @param VolumeMountPoint + * Pointer to string that contains either root drive name or + * mount point name. + * @param VolumeName + * Pointer to buffer that is filled with resulting unique + * volume name on success. + * @param VolumeNameLength + * Size of VolumeName buffer in TCHARs. + * + * @return + * TRUE when the function succeeds and the VolumeName buffer is filled, + * FALSE otherwise. + */ +BOOL +WINAPI +GetVolumeNameForVolumeMountPointW(IN LPCWSTR VolumeMountPoint, + OUT LPWSTR VolumeName, + IN DWORD VolumeNameLength) +{ + UNICODE_STRING NtFileName; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandle; + IO_STATUS_BLOCK Iosb; + ULONG BufferLength; + PMOUNTDEV_NAME MountDevName; + PMOUNTMGR_MOUNT_POINT MountPoint; + ULONG MountPointSize; + PMOUNTMGR_MOUNT_POINTS MountPoints; + ULONG Index; + PUCHAR SymbolicLinkName; + BOOL Result; + NTSTATUS Status; + + if (!VolumeMountPoint || !VolumeMountPoint[0]) + { + SetLastError(ERROR_PATH_NOT_FOUND); + return FALSE; + } + + /* + * First step is to convert the passed volume mount point name to + * an NT acceptable name. + */ + + if (!RtlDosPathNameToNtPathName_U(VolumeMountPoint, &NtFileName, NULL, NULL)) + { + SetLastError(ERROR_PATH_NOT_FOUND); + return FALSE; + } + + if (NtFileName.Length > sizeof(WCHAR) && + NtFileName.Buffer[(NtFileName.Length / sizeof(WCHAR)) - 1] == '\\') + { + NtFileName.Length -= sizeof(WCHAR); + } + + /* + * Query mount point device name which we will later use for determining + * the volume name. + */ + + InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL); + Status = NtOpenFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, &Iosb, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + RtlFreeUnicodeString(&NtFileName); + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + return FALSE; + } + + BufferLength = sizeof(MOUNTDEV_NAME) + 50 * sizeof(WCHAR); + do + { + MountDevName = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); + if (MountDevName == NULL) + { + NtClose(FileHandle); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, + IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, + NULL, 0, MountDevName, BufferLength); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(GetProcessHeap(), 0, MountDevName); + if (Status == STATUS_BUFFER_OVERFLOW) + { + BufferLength = sizeof(MOUNTDEV_NAME) + MountDevName->NameLength; + continue; + } + else + { + NtClose(FileHandle); + BaseSetLastNTError(Status); + return FALSE; + } + } + } + while (!NT_SUCCESS(Status)); + + NtClose(FileHandle); + + /* + * Get the mount point information from mount manager. + */ + + MountPointSize = MountDevName->NameLength + sizeof(MOUNTMGR_MOUNT_POINT); + MountPoint = RtlAllocateHeap(GetProcessHeap(), 0, MountPointSize); + if (MountPoint == NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, MountDevName); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + RtlZeroMemory(MountPoint, sizeof(MOUNTMGR_MOUNT_POINT)); + MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT); + MountPoint->DeviceNameLength = MountDevName->NameLength; + RtlCopyMemory(MountPoint + 1, MountDevName->Name, MountDevName->NameLength); + RtlFreeHeap(RtlGetProcessHeap(), 0, MountDevName); + + RtlInitUnicodeString(&NtFileName, L"\\??\\MountPointManager"); + InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL); + Status = NtOpenFile(&FileHandle, FILE_GENERIC_READ, &ObjectAttributes, + &Iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + return FALSE; + } + + BufferLength = sizeof(MOUNTMGR_MOUNT_POINTS); + do + { + MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); + if (MountPoints == NULL) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + NtClose(FileHandle); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, + IOCTL_MOUNTMGR_QUERY_POINTS, + MountPoint, MountPointSize, + MountPoints, BufferLength); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_BUFFER_OVERFLOW) + { + BufferLength = MountPoints->Size; + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + continue; + } + else if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + NtClose(FileHandle); + BaseSetLastNTError(Status); + return FALSE; + } + } + } + while (!NT_SUCCESS(Status)); + + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + NtClose(FileHandle); + + /* + * Now we've gathered info about all mount points mapped to our device, so + * select the correct one and copy it into the output buffer. + */ + + for (Index = 0; Index < MountPoints->NumberOfMountPoints; Index++) + { + MountPoint = MountPoints->MountPoints + Index; + SymbolicLinkName = (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset; + + /* + * Check for "\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\" + * (with the last slash being optional) style symbolic links. + */ + + if (MountPoint->SymbolicLinkNameLength == 48 * sizeof(WCHAR) || + (MountPoint->SymbolicLinkNameLength == 49 * sizeof(WCHAR) && + SymbolicLinkName[48] == L'\\')) + { + if (RtlCompareMemory(SymbolicLinkName, L"\\??\\Volume{", + 11 * sizeof(WCHAR)) == 11 * sizeof(WCHAR) && + SymbolicLinkName[19] == L'-' && SymbolicLinkName[24] == L'-' && + SymbolicLinkName[29] == L'-' && SymbolicLinkName[34] == L'-' && + SymbolicLinkName[47] == L'}') + { + if (VolumeNameLength >= MountPoint->SymbolicLinkNameLength / sizeof(WCHAR)) + { + RtlCopyMemory(VolumeName, + (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset, + MountPoint->SymbolicLinkNameLength); + VolumeName[1] = L'\\'; + Result = TRUE; + } + else + { + SetLastError(ERROR_FILENAME_EXCED_RANGE); + Result = FALSE; + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + + return Result; + } + } + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + SetLastError(ERROR_INVALID_PARAMETER); + + return FALSE; +} + +/* + * @implemented (Wine 13 sep 2008) + */ +BOOL +WINAPI +GetVolumeNameForVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint, + IN LPSTR lpszVolumeName, + IN DWORD cchBufferLength) +{ + BOOL ret; + WCHAR volumeW[50], *pathW = NULL; + DWORD len = min( sizeof(volumeW) / sizeof(WCHAR), cchBufferLength ); + + TRACE("(%s, %p, %x)\n", debugstr_a(lpszVolumeMountPoint), lpszVolumeName, cchBufferLength); + + if (!lpszVolumeMountPoint || !(pathW = FilenameA2W( lpszVolumeMountPoint, TRUE ))) + return FALSE; + + if ((ret = GetVolumeNameForVolumeMountPointW( pathW, volumeW, len ))) + FilenameW2A_N( lpszVolumeName, len, volumeW, -1 ); + + RtlFreeHeap( RtlGetProcessHeap(), 0, pathW ); + return ret; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +SetVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint, + IN LPCWSTR lpszVolumeName) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +SetVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint, + IN LPCSTR lpszVolumeName) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +DeleteVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +DeleteVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +HANDLE +WINAPI +FindFirstVolumeMountPointW(IN LPCWSTR lpszRootPathName, + IN LPWSTR lpszVolumeMountPoint, + IN DWORD cchBufferLength) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +HANDLE +WINAPI +FindFirstVolumeMountPointA(IN LPCSTR lpszRootPathName, + IN LPSTR lpszVolumeMountPoint, + IN DWORD cchBufferLength) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +FindNextVolumeMountPointA(IN HANDLE hFindVolumeMountPoint, + IN LPSTR lpszVolumeMountPoint, + DWORD cchBufferLength) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +FindNextVolumeMountPointW(IN HANDLE hFindVolumeMountPoint, + IN LPWSTR lpszVolumeMountPoint, + DWORD cchBufferLength) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +FindVolumeMountPointClose(IN HANDLE hFindVolumeMountPoint) +{ + STUB; + return 0; +} + +/* EOF */ diff --git a/reactos/dll/win32/kernel32/client/file/volume.c b/reactos/dll/win32/kernel32/client/file/volume.c index 62cc81bbf89..dedfb1c05b1 100644 --- a/reactos/dll/win32/kernel32/client/file/volume.c +++ b/reactos/dll/win32/kernel32/client/file/volume.c @@ -23,477 +23,66 @@ #include DEBUG_CHANNEL(kernel32file); -#define MAX_DOS_DRIVES 26 - - -static HANDLE -InternalOpenDirW(LPCWSTR DirName, - BOOLEAN Write) +HANDLE +WINAPI +InternalOpenDirW(IN LPCWSTR DirName, + IN BOOLEAN Write) { - UNICODE_STRING NtPathU; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS errCode; - IO_STATUS_BLOCK IoStatusBlock; - HANDLE hFile; + UNICODE_STRING NtPathU; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS errCode; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE hFile; - if (!RtlDosPathNameToNtPathName_U(DirName, - &NtPathU, - NULL, - NULL)) + if (!RtlDosPathNameToNtPathName_U(DirName, &NtPathU, NULL, NULL)) { - WARN("Invalid path\n"); - SetLastError(ERROR_BAD_PATHNAME); - return INVALID_HANDLE_VALUE; + WARN("Invalid path\n"); + SetLastError(ERROR_BAD_PATHNAME); + return INVALID_HANDLE_VALUE; } InitializeObjectAttributes(&ObjectAttributes, - &NtPathU, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); + &NtPathU, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); - errCode = NtCreateFile (&hFile, - Write ? FILE_GENERIC_WRITE : FILE_GENERIC_READ, - &ObjectAttributes, - &IoStatusBlock, - NULL, - 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_OPEN, - 0, - NULL, - 0); + errCode = NtCreateFile(&hFile, + Write ? FILE_GENERIC_WRITE : FILE_GENERIC_READ, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + 0, + NULL, + 0); - RtlFreeHeap(RtlGetProcessHeap(), - 0, - NtPathU.Buffer); + RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathU.Buffer); if (!NT_SUCCESS(errCode)) { - BaseSetLastNTError (errCode); - return INVALID_HANDLE_VALUE; + BaseSetLastNTError(errCode); + return INVALID_HANDLE_VALUE; } + return hFile; } - /* * @implemented */ -/* Synced to Wine-2008/12/28 */ -DWORD WINAPI -GetLogicalDriveStringsA(DWORD nBufferLength, - LPSTR lpBuffer) -{ - DWORD drive, count; - DWORD dwDriveMap; - LPSTR p; - - dwDriveMap = GetLogicalDrives(); - - for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++) - { - if (dwDriveMap & (1< nBufferLength) return ((count * 4) + 1); - - p = lpBuffer; - - for (drive = 0; drive < MAX_DOS_DRIVES; drive++) - if (dwDriveMap & (1< nBufferLength) return ((count * 4) + 1); - - p = lpBuffer; - for (drive = 0; drive < MAX_DOS_DRIVES; drive++) - if (dwDriveMap & (1<QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsFullSize.CallerAvailableAllocationUnits.QuadPart; - } - - if (lpTotalNumberOfBytes != NULL) - { - lpTotalNumberOfBytes->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsFullSize.TotalAllocationUnits.QuadPart; - } - - if (lpTotalNumberOfFreeBytes != NULL) - { - lpTotalNumberOfFreeBytes->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsFullSize.ActualAvailableAllocationUnits.QuadPart; - } - - return TRUE; - } - } - - Status = NtQueryVolumeInformationFile(hFile, - &IoStatusBlock, - &FsInfo.FsSize, - sizeof(FsInfo.FsSize), - FileFsSizeInformation); - - /* Close the handle before returning data - to avoid a handle leak in case of a fault! */ - CloseHandle(hFile); - - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError (Status); - return FALSE; - } - - BytesPerCluster.QuadPart = - FsInfo.FsSize.BytesPerSector * FsInfo.FsSize.SectorsPerAllocationUnit; - - if (lpFreeBytesAvailableToCaller) - { - lpFreeBytesAvailableToCaller->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; - } - - if (lpTotalNumberOfBytes) - { - lpTotalNumberOfBytes->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsSize.TotalAllocationUnits.QuadPart; - } - - if (lpTotalNumberOfFreeBytes) - { - lpTotalNumberOfFreeBytes->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; - } - - return TRUE; -} - - -/* - * @implemented - */ -UINT WINAPI -GetDriveTypeA(LPCSTR lpRootPathName) -{ - PWCHAR RootPathNameW; - - if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE))) - return DRIVE_UNKNOWN; - - return GetDriveTypeW(RootPathNameW); -} - - -/* - * @implemented - */ -UINT WINAPI -GetDriveTypeW(LPCWSTR lpRootPathName) -{ - FILE_FS_DEVICE_INFORMATION FileFsDevice; - IO_STATUS_BLOCK IoStatusBlock; - - HANDLE hFile; - NTSTATUS errCode; - - hFile = InternalOpenDirW(lpRootPathName, FALSE); - if (hFile == INVALID_HANDLE_VALUE) - { - return DRIVE_NO_ROOT_DIR; /* According to WINE regression tests */ - } - - errCode = NtQueryVolumeInformationFile (hFile, - &IoStatusBlock, - &FileFsDevice, - sizeof(FILE_FS_DEVICE_INFORMATION), - FileFsDeviceInformation); - if (!NT_SUCCESS(errCode)) - { - CloseHandle(hFile); - BaseSetLastNTError (errCode); - return 0; - } - CloseHandle(hFile); - - switch (FileFsDevice.DeviceType) - { - case FILE_DEVICE_CD_ROM: - case FILE_DEVICE_CD_ROM_FILE_SYSTEM: - return DRIVE_CDROM; - case FILE_DEVICE_VIRTUAL_DISK: - return DRIVE_RAMDISK; - case FILE_DEVICE_NETWORK_FILE_SYSTEM: - return DRIVE_REMOTE; - case FILE_DEVICE_DISK: - case FILE_DEVICE_DISK_FILE_SYSTEM: - if (FileFsDevice.Characteristics & FILE_REMOTE_DEVICE) - return DRIVE_REMOTE; - if (FileFsDevice.Characteristics & FILE_REMOVABLE_MEDIA) - return DRIVE_REMOVABLE; - return DRIVE_FIXED; - } - - ERR("Returning DRIVE_UNKNOWN for device type %d\n", FileFsDevice.DeviceType); - - return DRIVE_UNKNOWN; -} - - -/* - * @implemented - */ -BOOL WINAPI -GetVolumeInformationA( - LPCSTR lpRootPathName, - LPSTR lpVolumeNameBuffer, - DWORD nVolumeNameSize, - LPDWORD lpVolumeSerialNumber, - LPDWORD lpMaximumComponentLength, - LPDWORD lpFileSystemFlags, - LPSTR lpFileSystemNameBuffer, - DWORD nFileSystemNameSize - ) +BOOL +WINAPI +GetVolumeInformationA(IN LPCSTR lpRootPathName, + IN LPSTR lpVolumeNameBuffer, + IN DWORD nVolumeNameSize, + OUT LPDWORD lpVolumeSerialNumber OPTIONAL, + OUT LPDWORD lpMaximumComponentLength OPTIONAL, + OUT LPDWORD lpFileSystemFlags OPTIONAL, + OUT LPSTR lpFileSystemNameBuffer OPTIONAL, + IN DWORD nFileSystemNameSize) { UNICODE_STRING FileSystemNameU; UNICODE_STRING VolumeNameU = { 0, 0, NULL }; @@ -622,17 +211,16 @@ FailNoMem: /* * @implemented */ -BOOL WINAPI -GetVolumeInformationW( - LPCWSTR lpRootPathName, - LPWSTR lpVolumeNameBuffer, - DWORD nVolumeNameSize, - LPDWORD lpVolumeSerialNumber, - LPDWORD lpMaximumComponentLength, - LPDWORD lpFileSystemFlags, - LPWSTR lpFileSystemNameBuffer, - DWORD nFileSystemNameSize - ) +BOOL +WINAPI +GetVolumeInformationW(IN LPCWSTR lpRootPathName, + IN LPWSTR lpVolumeNameBuffer, + IN DWORD nVolumeNameSize, + OUT LPDWORD lpVolumeSerialNumber OPTIONAL, + OUT LPDWORD lpMaximumComponentLength OPTIONAL, + OUT LPDWORD lpFileSystemFlags OPTIONAL, + OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, + IN DWORD nFileSystemNameSize) { PFILE_FS_VOLUME_INFORMATION FileFsVolume; PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute; @@ -734,16 +322,13 @@ GetVolumeInformationW( return TRUE; } - /* * @implemented */ BOOL WINAPI -SetVolumeLabelA ( - LPCSTR lpRootPathName, - LPCSTR lpVolumeName /* NULL if deleting label */ - ) +SetVolumeLabelA(IN LPCSTR lpRootPathName, + IN LPCSTR lpVolumeName OPTIONAL) /* NULL if deleting label */ { PWCHAR RootPathNameW; PWCHAR VolumeNameW = NULL; @@ -771,15 +356,13 @@ SetVolumeLabelA ( return Result; } - /* * @implemented */ -BOOL WINAPI -SetVolumeLabelW( - LPCWSTR lpRootPathName, - LPCWSTR lpVolumeName /* NULL if deleting label */ - ) +BOOL +WINAPI +SetVolumeLabelW(IN LPCWSTR lpRootPathName, + IN LPCWSTR lpVolumeName OPTIONAL) /* NULL if deleting label */ { PFILE_FS_LABEL_INFORMATION LabelInfo; IO_STATUS_BLOCK IoStatusBlock; @@ -834,276 +417,13 @@ SetVolumeLabelW( return TRUE; } -/** - * @name GetVolumeNameForVolumeMountPointW - * - * Return an unique volume name for a drive root or mount point. - * - * @param VolumeMountPoint - * Pointer to string that contains either root drive name or - * mount point name. - * @param VolumeName - * Pointer to buffer that is filled with resulting unique - * volume name on success. - * @param VolumeNameLength - * Size of VolumeName buffer in TCHARs. - * - * @return - * TRUE when the function succeeds and the VolumeName buffer is filled, - * FALSE otherwise. - */ - -BOOL WINAPI -GetVolumeNameForVolumeMountPointW( - IN LPCWSTR VolumeMountPoint, - OUT LPWSTR VolumeName, - IN DWORD VolumeNameLength) -{ - UNICODE_STRING NtFileName; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE FileHandle; - IO_STATUS_BLOCK Iosb; - ULONG BufferLength; - PMOUNTDEV_NAME MountDevName; - PMOUNTMGR_MOUNT_POINT MountPoint; - ULONG MountPointSize; - PMOUNTMGR_MOUNT_POINTS MountPoints; - ULONG Index; - PUCHAR SymbolicLinkName; - BOOL Result; - NTSTATUS Status; - - if (!VolumeMountPoint || !VolumeMountPoint[0]) - { - SetLastError(ERROR_PATH_NOT_FOUND); - return FALSE; - } - - /* - * First step is to convert the passed volume mount point name to - * an NT acceptable name. - */ - - if (!RtlDosPathNameToNtPathName_U(VolumeMountPoint, &NtFileName, NULL, NULL)) - { - SetLastError(ERROR_PATH_NOT_FOUND); - return FALSE; - } - - if (NtFileName.Length > sizeof(WCHAR) && - NtFileName.Buffer[(NtFileName.Length / sizeof(WCHAR)) - 1] == '\\') - { - NtFileName.Length -= sizeof(WCHAR); - } - - /* - * Query mount point device name which we will later use for determining - * the volume name. - */ - - InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL); - Status = NtOpenFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, - &ObjectAttributes, &Iosb, - FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_SYNCHRONOUS_IO_NONALERT); - RtlFreeUnicodeString(&NtFileName); - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError(Status); - return FALSE; - } - - BufferLength = sizeof(MOUNTDEV_NAME) + 50 * sizeof(WCHAR); - do - { - MountDevName = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); - if (MountDevName == NULL) - { - NtClose(FileHandle); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, - IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, - NULL, 0, MountDevName, BufferLength); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(GetProcessHeap(), 0, MountDevName); - if (Status == STATUS_BUFFER_OVERFLOW) - { - BufferLength = sizeof(MOUNTDEV_NAME) + MountDevName->NameLength; - continue; - } - else - { - NtClose(FileHandle); - BaseSetLastNTError(Status); - return FALSE; - } - } - } - while (!NT_SUCCESS(Status)); - - NtClose(FileHandle); - - /* - * Get the mount point information from mount manager. - */ - - MountPointSize = MountDevName->NameLength + sizeof(MOUNTMGR_MOUNT_POINT); - MountPoint = RtlAllocateHeap(GetProcessHeap(), 0, MountPointSize); - if (MountPoint == NULL) - { - RtlFreeHeap(GetProcessHeap(), 0, MountDevName); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - RtlZeroMemory(MountPoint, sizeof(MOUNTMGR_MOUNT_POINT)); - MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT); - MountPoint->DeviceNameLength = MountDevName->NameLength; - RtlCopyMemory(MountPoint + 1, MountDevName->Name, MountDevName->NameLength); - RtlFreeHeap(RtlGetProcessHeap(), 0, MountDevName); - - RtlInitUnicodeString(&NtFileName, L"\\??\\MountPointManager"); - InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL); - Status = NtOpenFile(&FileHandle, FILE_GENERIC_READ, &ObjectAttributes, - &Iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError(Status); - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); - return FALSE; - } - - BufferLength = sizeof(MOUNTMGR_MOUNT_POINTS); - do - { - MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); - if (MountPoints == NULL) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); - NtClose(FileHandle); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, - IOCTL_MOUNTMGR_QUERY_POINTS, - MountPoint, MountPointSize, - MountPoints, BufferLength); - if (!NT_SUCCESS(Status)) - { - if (Status == STATUS_BUFFER_OVERFLOW) - { - BufferLength = MountPoints->Size; - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); - continue; - } - else if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); - NtClose(FileHandle); - BaseSetLastNTError(Status); - return FALSE; - } - } - } - while (!NT_SUCCESS(Status)); - - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); - NtClose(FileHandle); - - /* - * Now we've gathered info about all mount points mapped to our device, so - * select the correct one and copy it into the output buffer. - */ - - for (Index = 0; Index < MountPoints->NumberOfMountPoints; Index++) - { - MountPoint = MountPoints->MountPoints + Index; - SymbolicLinkName = (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset; - - /* - * Check for "\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\" - * (with the last slash being optional) style symbolic links. - */ - - if (MountPoint->SymbolicLinkNameLength == 48 * sizeof(WCHAR) || - (MountPoint->SymbolicLinkNameLength == 49 * sizeof(WCHAR) && - SymbolicLinkName[48] == L'\\')) - { - if (RtlCompareMemory(SymbolicLinkName, L"\\??\\Volume{", - 11 * sizeof(WCHAR)) == 11 * sizeof(WCHAR) && - SymbolicLinkName[19] == L'-' && SymbolicLinkName[24] == L'-' && - SymbolicLinkName[29] == L'-' && SymbolicLinkName[34] == L'-' && - SymbolicLinkName[47] == L'}') - { - if (VolumeNameLength >= MountPoint->SymbolicLinkNameLength / sizeof(WCHAR)) - { - RtlCopyMemory(VolumeName, - (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset, - MountPoint->SymbolicLinkNameLength); - VolumeName[1] = L'\\'; - Result = TRUE; - } - else - { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - Result = FALSE; - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); - - return Result; - } - } - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); - SetLastError(ERROR_INVALID_PARAMETER); - - return FALSE; -} - -/* - * @implemented (Wine 13 sep 2008) - */ -BOOL -WINAPI -GetVolumeNameForVolumeMountPointA( - LPCSTR lpszVolumeMountPoint, - LPSTR lpszVolumeName, - DWORD cchBufferLength - ) -{ - BOOL ret; - WCHAR volumeW[50], *pathW = NULL; - DWORD len = min( sizeof(volumeW) / sizeof(WCHAR), cchBufferLength ); - - TRACE("(%s, %p, %x)\n", debugstr_a(lpszVolumeMountPoint), lpszVolumeName, cchBufferLength); - - if (!lpszVolumeMountPoint || !(pathW = FilenameA2W( lpszVolumeMountPoint, TRUE ))) - return FALSE; - - if ((ret = GetVolumeNameForVolumeMountPointW( pathW, volumeW, len ))) - FilenameW2A_N( lpszVolumeName, len, volumeW, -1 ); - - RtlFreeHeap( RtlGetProcessHeap(), 0, pathW ); - return ret; -} - /* * @implemented (Wine 13 sep 2008) */ HANDLE WINAPI -FindFirstVolumeW( - LPWSTR volume, - DWORD len - ) +FindFirstVolumeW(IN LPWSTR volume, + IN DWORD len) { DWORD size = 1024; HANDLE mgr = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, @@ -1149,10 +469,8 @@ FindFirstVolumeW( */ HANDLE WINAPI -FindFirstVolumeA( - LPSTR volume, - DWORD len - ) +FindFirstVolumeA(IN LPSTR volume, + IN DWORD len) { WCHAR *buffer = NULL; HANDLE handle; @@ -1184,9 +502,7 @@ FindFirstVolumeA( */ BOOL WINAPI -FindVolumeClose( - HANDLE hFindVolume - ) +FindVolumeClose(IN HANDLE hFindVolume) { return RtlFreeHeap(RtlGetProcessHeap(), 0, hFindVolume); } @@ -1196,9 +512,9 @@ FindVolumeClose( */ BOOL WINAPI -GetVolumePathNameA(LPCSTR lpszFileName, - LPSTR lpszVolumePathName, - DWORD cchBufferLength) +GetVolumePathNameA(IN LPCSTR lpszFileName, + IN LPSTR lpszVolumePathName, + IN DWORD cchBufferLength) { PWCHAR FileNameW = NULL; WCHAR VolumePathName[MAX_PATH]; @@ -1223,9 +539,9 @@ GetVolumePathNameA(LPCSTR lpszFileName, */ BOOL WINAPI -GetVolumePathNameW(LPCWSTR lpszFileName, - LPWSTR lpszVolumePathName, - DWORD cchBufferLength) +GetVolumePathNameW(IN LPCWSTR lpszFileName, + IN LPWSTR lpszVolumePathName, + IN DWORD cchBufferLength) { DWORD PathLength; UNICODE_STRING UnicodeFilePath; @@ -1329,57 +645,14 @@ Cleanup2: return Result; } - -/* - * @unimplemented - */ -BOOL -WINAPI -SetVolumeMountPointW( - LPCWSTR lpszVolumeMountPoint, - LPCWSTR lpszVolumeName - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -DeleteVolumeMountPointA( - LPCSTR lpszVolumeMountPoint - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -HANDLE -WINAPI -FindFirstVolumeMountPointA( - LPCSTR lpszRootPathName, - LPSTR lpszVolumeMountPoint, - DWORD cchBufferLength - ) -{ - STUB; - return 0; -} - /* * @implemented */ BOOL WINAPI -FindNextVolumeA(HANDLE handle, - LPSTR volume, - DWORD len) +FindNextVolumeA(IN HANDLE handle, + IN LPSTR volume, + IN DWORD len) { WCHAR *buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, len * sizeof(WCHAR)); BOOL ret; @@ -1399,102 +672,14 @@ FindNextVolumeA(HANDLE handle, return ret; } -/* - * @unimplemented - */ -BOOL -WINAPI -FindNextVolumeMountPointA( - HANDLE hFindVolumeMountPoint, - LPSTR lpszVolumeMountPoint, - DWORD cchBufferLength - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -GetVolumePathNamesForVolumeNameA( - LPCSTR lpszVolumeName, - LPSTR lpszVolumePathNames, - DWORD cchBufferLength, - PDWORD lpcchReturnLength - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -SetVolumeMountPointA( - LPCSTR lpszVolumeMountPoint, - LPCSTR lpszVolumeName - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -FindVolumeMountPointClose( - HANDLE hFindVolumeMountPoint - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -DeleteVolumeMountPointW( - LPCWSTR lpszVolumeMountPoint - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -HANDLE -WINAPI -FindFirstVolumeMountPointW( - LPCWSTR lpszRootPathName, - LPWSTR lpszVolumeMountPoint, - DWORD cchBufferLength - ) -{ - STUB; - return 0; -} - /* * @implemented */ BOOL WINAPI -FindNextVolumeW( - HANDLE handle, - LPWSTR volume, - DWORD len - ) +FindNextVolumeW(IN HANDLE handle, + IN LPWSTR volume, + IN DWORD len) { MOUNTMGR_MOUNT_POINTS *data = handle; @@ -1527,31 +712,28 @@ FindNextVolumeW( */ BOOL WINAPI -FindNextVolumeMountPointW( - HANDLE hFindVolumeMountPoint, - LPWSTR lpszVolumeMountPoint, - DWORD cchBufferLength - ) +GetVolumePathNamesForVolumeNameA(IN LPCSTR lpszVolumeName, + IN LPSTR lpszVolumePathNames, + IN DWORD cchBufferLength, + OUT PDWORD lpcchReturnLength) { STUB; return 0; } + /* * @unimplemented */ BOOL WINAPI -GetVolumePathNamesForVolumeNameW( - LPCWSTR lpszVolumeName, - LPWSTR lpszVolumePathNames, - DWORD cchBufferLength, - PDWORD lpcchReturnLength - ) +GetVolumePathNamesForVolumeNameW(IN LPCWSTR lpszVolumeName, + IN LPWSTR lpszVolumePathNames, + IN DWORD cchBufferLength, + OUT PDWORD lpcchReturnLength) { STUB; return 0; } - /* EOF */ From 110bbab440be20df3f9d5f81c8926becf744aa08 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 4 Aug 2013 18:46:07 +0000 Subject: [PATCH 03/25] [KERNEL32]: Fix a few bugs in StuffStdHandle. Ironically Windows Server 2003 actually has a bug here when calling NtDuplicateObject... svn path=/trunk/; revision=59639 --- reactos/dll/win32/kernel32/client/proc.c | 53 +++++++++++++----------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index f844b8b17db..5d129d3950e 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -62,22 +62,27 @@ StuffStdHandle(IN HANDLE ProcessHandle, HANDLE DuplicatedHandle; SIZE_T Dummy; - /* Duplicate the handle */ - Status = NtDuplicateObject(NtCurrentProcess(), - StandardHandle, - ProcessHandle, - &DuplicatedHandle, - 0, - 0, - DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES); - if (NT_SUCCESS(Status)) + /* Is there a handle to duplicate? */ + if (StandardHandle) { - /* Write it */ - NtWriteVirtualMemory(ProcessHandle, - Address, - &DuplicatedHandle, - sizeof(HANDLE), - &Dummy); + /* Duplicate it */ + Status = NtDuplicateObject(NtCurrentProcess(), + StandardHandle, + ProcessHandle, + &DuplicatedHandle, + 0, + 0, + DUPLICATE_SAME_ACCESS | + DUPLICATE_SAME_ATTRIBUTES); + if (NT_SUCCESS(Status)) + { + /* Write it */ + NtWriteVirtualMemory(ProcessHandle, + Address, + &DuplicatedHandle, + sizeof(HANDLE), + &Dummy); + } } } @@ -4139,25 +4144,25 @@ StartScan: /* Duplicate standard input unless it's a console handle */ if (!IsConsoleHandle(Peb->ProcessParameters->StandardInput)) { - StuffStdHandle(&ProcessParameters->StandardInput, - ProcessHandle, - Peb->ProcessParameters->StandardInput); + StuffStdHandle(ProcessHandle, + Peb->ProcessParameters->StandardInput, + &ProcessParameters->StandardInput); } /* Duplicate standard output unless it's a console handle */ if (!IsConsoleHandle(Peb->ProcessParameters->StandardOutput)) { - StuffStdHandle(&ProcessParameters->StandardOutput, - ProcessHandle, - Peb->ProcessParameters->StandardOutput); + StuffStdHandle(ProcessHandle, + Peb->ProcessParameters->StandardOutput, + &ProcessParameters->StandardOutput); } /* Duplicate standard error unless it's a console handle */ if (!IsConsoleHandle(Peb->ProcessParameters->StandardError)) { - StuffStdHandle(&ProcessParameters->StandardError, - ProcessHandle, - Peb->ProcessParameters->StandardError); + StuffStdHandle(ProcessHandle, + Peb->ProcessParameters->StandardError, + &ProcessParameters->StandardError); } } } From 6c25276f318accb338c8db33b23b658bf22af883 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 4 Aug 2013 19:28:37 +0000 Subject: [PATCH 04/25] [NDK/NTOSKRNL]: Use correct flags. Spotted by Thomas Fabber. svn path=/trunk/; revision=59640 --- reactos/include/ndk/pstypes.h | 26 ++++++++++---------------- reactos/ntoskrnl/ps/process.c | 15 ++++++++------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index 86fc1b05f94..caeb127e080 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -89,11 +89,17 @@ extern POBJECT_TYPE NTSYSAPI PsJobType; // // Flags for NtCreateProcessEx // -#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 -#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 -#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 +#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 +#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 +#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 #define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008 -#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010 +#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010 +#define PROCESS_CREATE_FLAGS_ALL_LARGE_PAGE_FLAGS PROCESS_CREATE_FLAGS_LARGE_PAGES +#define PROCESS_CREATE_FLAGS_LEGAL_MASK (PROCESS_CREATE_FLAGS_BREAKAWAY | \ + PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT | \ + PROCESS_CREATE_FLAGS_INHERIT_HANDLES | \ + PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE | \ + PROCESS_CREATE_FLAGS_ALL_LARGE_PAGE_FLAGS) // // Process priority classes @@ -106,18 +112,6 @@ extern POBJECT_TYPE NTSYSAPI PsJobType; #define PROCESS_PRIORITY_CLASS_BELOW_NORMAL 5 #define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL 6 -// -// NtCreateProcessEx flags -// -#define PS_REQUEST_BREAKAWAY 1 -#define PS_NO_DEBUG_INHERIT 2 -#define PS_INHERIT_HANDLES 4 -#define PS_LARGE_PAGES 8 -#define PS_ALL_FLAGS (PS_REQUEST_BREAKAWAY | \ - PS_NO_DEBUG_INHERIT | \ - PS_INHERIT_HANDLES | \ - PS_LARGE_PAGES) - // // Process base priorities // diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 2a00366c896..1f881e65826 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -369,7 +369,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, "ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess); /* Validate flags */ - if (Flags & ~PS_ALL_FLAGS) return STATUS_INVALID_PARAMETER; + if (Flags & ~PROCESS_CREATE_FLAGS_LEGAL_MASK) return STATUS_INVALID_PARAMETER; /* Check for parent */ if (ParentProcess) @@ -508,7 +508,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, Process->DebugPort = DebugObject; /* Check if the caller doesn't want the debug stuff inherited */ - if (Flags & PS_NO_DEBUG_INHERIT) + if (Flags & PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT) { /* Set the process flag */ InterlockedOr((PLONG)&Process->Flags, PSF_NO_DEBUG_INHERIT_BIT); @@ -595,7 +595,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, } /* Initialize object manager for the process */ - Status = ObInitProcess(Flags & PS_INHERIT_HANDLES ? Parent : NULL, + Status = ObInitProcess(Flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES ? + Parent : NULL, Process); if (!NT_SUCCESS(Status)) goto CleanupWithRef; } @@ -643,7 +644,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, else { /* This is the initial system process */ - Flags &= ~PS_LARGE_PAGES; + Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES; Status = MmInitializeProcessAddressSpace(Process, NULL, NULL, @@ -1347,9 +1348,9 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, "Parent: %p Attributes: %p\n", ParentProcess, ObjectAttributes); /* Set new-style flags */ - if ((ULONG)SectionHandle & 1) Flags = PS_REQUEST_BREAKAWAY; - if ((ULONG)DebugPort & 1) Flags |= PS_NO_DEBUG_INHERIT; - if (InheritObjectTable) Flags |= PS_INHERIT_HANDLES; + if ((ULONG)SectionHandle & 1) Flags |= PROCESS_CREATE_FLAGS_BREAKAWAY; + if ((ULONG)DebugPort & 1) Flags |= PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT; + if (InheritObjectTable) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES; /* Call the new API */ return NtCreateProcessEx(ProcessHandle, From 372e1e2bd09a07a442b45e5eb10b6d905c6c2781 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 4 Aug 2013 20:28:26 +0000 Subject: [PATCH 05/25] [SYSSETUP] Add missing class installer stubs. svn path=/trunk/; revision=59641 --- reactos/dll/win32/syssetup/classinst.c | 98 ++++++++++++++++++++++++ reactos/dll/win32/syssetup/syssetup.spec | 10 +-- 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/reactos/dll/win32/syssetup/classinst.c b/reactos/dll/win32/syssetup/classinst.c index dc853e9df4e..5c3a4d0a754 100644 --- a/reactos/dll/win32/syssetup/classinst.c +++ b/reactos/dll/win32/syssetup/classinst.c @@ -11,6 +11,45 @@ #define NDEBUG #include + +/* + * @unimplemented + */ +DWORD +WINAPI +ComputerClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT1("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + + +/* + * @unimplemented + */ +DWORD +WINAPI +DeviceBayClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + + /* * @implemented */ @@ -61,3 +100,62 @@ MouseClassInstaller( return ERROR_DI_DO_DEFAULT; } } + + +/* + * @unimplemented + */ +DWORD +WINAPI +NtApmClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + + +/* + * @unimplemented + */ +DWORD +WINAPI +ScsiClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + + +/* + * @unimplemented + */ +DWORD +WINAPI +TapeClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + +/* EOF */ diff --git a/reactos/dll/win32/syssetup/syssetup.spec b/reactos/dll/win32/syssetup/syssetup.spec index 4b37986a416..e2f4a1d8296 100644 --- a/reactos/dll/win32/syssetup/syssetup.spec +++ b/reactos/dll/win32/syssetup/syssetup.spec @@ -8,13 +8,13 @@ @ stub AsrpGetLocalVolumeInfo @ stub AsprRestoreNonCriticalDisksW @ stub CdromPropPageProvider -@ stub ComputerClassInstaller +@ stdcall ComputerClassInstaller(long ptr ptr) @ stub CreateLocalAdminAccount @ stub CreateLocalAdminAccountEx @ stub CreateLocalUserAccount @ stub CriticalDeviceCoInstaller @ stub DevInstallW -@ stub DeviceBayClassInstaller +@ stdcall DeviceBayClassInstaller(long ptr ptr) @ stub DiskPropPageProvider @ stub DoInstallComponentInfs @ stub EisaUpHalCoInstaller @@ -29,7 +29,7 @@ @ stub LegacyDriverPropPageProvider @ stub MigrateExceptionPackages @ stdcall MouseClassInstaller(long ptr ptr) -@ stub NtApmClassInstaller +@ stdcall NtApmClassInstaller(long ptr ptr) @ stub OpkCheckVersion @ stub PS2MousePropPageProvider @ stub PnPInitializationThread @@ -37,7 +37,7 @@ @ stub RepairStartMenuItems @ stub ReportError @ stub RunOEMExtraTasks -@ stub ScsiClassInstaller +@ stdcall ScsiClassInstaller(long ptr ptr) @ stub SetAccountDomainSid @ stub SetupAddOrRemoveTestCertificate @ stdcall SetupChangeFontSize(ptr wstr) @@ -76,7 +76,7 @@ @ stub SetupUnregisterOsComponent @ stub StorageCoInstaller @ stub SystemUpdateUserProfileDirectory -@ stub TapeClassInstaller +@ stdcall TapeClassInstaller(long ptr ptr) @ stub TapePropPageProvider @ stdcall TerminateSetupActionLog() @ stub UpdatePnpDeviceDrivers From b5dd9550f87c9d27fee4b4955c578a45d4a78978 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 4 Aug 2013 20:46:55 +0000 Subject: [PATCH 06/25] [KERNEL32]: Fix incorrect bracing which was causing SearchPath failures to enter a weird code path. Fix a debug print. svn path=/trunk/; revision=59642 --- reactos/dll/win32/kernel32/client/path.c | 2 +- reactos/dll/win32/kernel32/client/proc.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/path.c b/reactos/dll/win32/kernel32/client/path.c index a6e1692a909..4b73357d745 100644 --- a/reactos/dll/win32/kernel32/client/path.c +++ b/reactos/dll/win32/kernel32/client/path.c @@ -401,7 +401,7 @@ WINAPI BaseComputeProcessExePath(IN LPWSTR FullPath) { PBASE_SEARCH_PATH_TYPE PathOrder; - DPRINT1("Computing EXE path: %wZ\n", FullPath); + DPRINT1("Computing EXE path: %S\n", FullPath); /* Check if we should use the current directory */ PathOrder = NeedCurrentDirectoryForExePathW(FullPath) ? diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index 5d129d3950e..23f059a338e 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -2733,11 +2733,11 @@ StartScan: /* This was a directory, fail later on */ Length = 0; } - } - else - { - /* It's a file! */ - Length++; + else + { + /* It's a file! */ + Length++; + } } DPRINT1("Length: %lx Buffer: %S\n", Length, NameBuffer); From 467ca7e83e9e11dca60cde1495cceae0afc0bcc3 Mon Sep 17 00:00:00 2001 From: Ziliang Guo Date: Mon, 5 Aug 2013 17:24:09 +0000 Subject: [PATCH 07/25] [VGAFONTEDIT] Add Chinese translation for VGA font edit utility. ROSAPPS-254 #resolve svn path=/trunk/; revision=59643 --- .../devutils/vgafontedit/lang/zh-CN.rc | 94 +++++++++++++++++++ .../applications/devutils/vgafontedit/rsrc.rc | 3 + 2 files changed, 97 insertions(+) create mode 100644 rosapps/applications/devutils/vgafontedit/lang/zh-CN.rc diff --git a/rosapps/applications/devutils/vgafontedit/lang/zh-CN.rc b/rosapps/applications/devutils/vgafontedit/lang/zh-CN.rc new file mode 100644 index 00000000000..c1c092aa80f --- /dev/null +++ b/rosapps/applications/devutils/vgafontedit/lang/zh-CN.rc @@ -0,0 +1,94 @@ +/* + * PROJECT: ReactOS VGA Font Editor + * LICENSE: GNU General Public License Version 2.0 or any later version + * FILE: devutils/vgafontedit/lang/zh-CN.rc + * PURPOSE: Simplified Chinese resource file + * COPYRIGHT: Copyright 2008 Colin Finck + * TRANSLATOR: BinSys + */ + +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED + +IDD_ABOUT DIALOGEX 10, 10, 130, 62 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "关于" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_MAIN, IDC_STATIC, 10, 10, 20, 20 + LTEXT "ReactOS VGA 字体 编辑器", IDC_STATIC, 37, 10, 93, 10 + LTEXT "Copyright 2008 Colin Finck", IDC_STATIC, 37, 20, 93, 10 + DEFPUSHBUTTON "确定", IDCANCEL, 40, 44, 55, 15 +END + +IDD_EDITGLYPH DIALOGEX 32768, 32768, 246, 197 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "编辑 字形" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_EDIT_GLYPH_TOOLBOX, TOOLBARCLASSNAMEA, CCS_NODIVIDER | CCS_NORESIZE, 5, 5, 24, 82 + CONTROL "", IDC_EDIT_GLYPH_EDIT, EDIT_GLYPH_EDIT_CLASSW, 0, 39, 5, 160, 160 + CONTROL "", IDC_EDIT_GLYPH_PREVIEW, EDIT_GLYPH_PREVIEW_CLASSW, 0, 209, 5, 32, 32 + + DEFPUSHBUTTON "确定", IDOK, 48, 177, 70, 14 + PUSHBUTTON "取消", IDCANCEL, 125, 177, 70, 14 +END + +IDM_MAINMENU MENU +BEGIN + POPUP "文件(&F)" + BEGIN + MENUITEM "新建(&N)\tCtrl+N", ID_FILE_NEW + MENUITEM "打开(&O)...\tCtrl+O", ID_FILE_OPEN + MENUITEM "关闭", ID_FILE_CLOSE + MENUITEM SEPARATOR + MENUITEM "保存\tCtrl+S", ID_FILE_SAVE + MENUITEM "另存为...", ID_FILE_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "退出\tAlt+F4", ID_FILE_EXIT + END + + POPUP "编辑(&E)" + BEGIN + MENUITEM "复制\tCtrl+C", ID_EDIT_COPY + MENUITEM "粘贴\tCtrl+V", ID_EDIT_PASTE + MENUITEM SEPARATOR + MENUITEM "编辑 字形...", ID_EDIT_GLYPH + END + + POPUP "窗口(&W)" + BEGIN + MENUITEM "层叠(&C)", ID_WINDOW_CASCADE + MENUITEM "水平平铺(&H)", ID_WINDOW_TILE_HORZ + MENUITEM "垂直平铺(&V)", ID_WINDOW_TILE_VERT + MENUITEM "排列图标(&A)", ID_WINDOW_ARRANGE + MENUITEM SEPARATOR + MENUITEM "下一个(&t)\tCtrl+F6", ID_WINDOW_NEXT + END + + POPUP "帮助(&H)" + BEGIN + MENUITEM "关于(&A)...", ID_HELP_ABOUT + END +END + +STRINGTABLE +BEGIN + IDS_OPENFILTER, "全部支持的格式 (*.bin,*.psf)|*.bin;*.psf|Binary Font Files (*.bin)|*.bin|PC Screen Fonts Version 1 (*.psf)|*.psf|" + IDS_SAVEFILTER, "二进制字体文件 (*.bin)|*.bin|" + IDS_OPENERROR, "打开文件时发生错误! (错误码 %1!u!)" + IDS_READERROR, "读取文件时发生错误! (错误码 %1!u!)" + IDS_WRITEERROR, "写入文件时发生错误! (错误码 %1!u!)" + IDS_UNSUPPORTEDFORMAT, "不支持的文件格式!" + IDS_UNSUPPORTEDPSF, "不支持的 PSF 字体格式! 编辑器仅支持非特殊模式 8x8 字体。" + IDS_DOCNAME, "字体 %1!u!" + IDS_SAVEPROMPT, "文件 ""%1"" 已更改,但未保存.\n\n是否保存文件?" + IDS_APPTITLE, "ReactOS VGA 字体 编辑器" + IDS_CLOSEEDIT, "请先关闭全部打开的编辑窗口。" + + IDS_TOOLTIP_NEW, "新建" + IDS_TOOLTIP_OPEN, "打开" + IDS_TOOLTIP_SAVE, "保存" + IDS_TOOLTIP_EDIT_GLYPH, "编辑 字形" + IDS_TOOLTIP_COPY, "复制" + IDS_TOOLTIP_PASTE, "粘贴" +END diff --git a/rosapps/applications/devutils/vgafontedit/rsrc.rc b/rosapps/applications/devutils/vgafontedit/rsrc.rc index 826608bddb9..3c06d6bd52a 100644 --- a/rosapps/applications/devutils/vgafontedit/rsrc.rc +++ b/rosapps/applications/devutils/vgafontedit/rsrc.rc @@ -43,3 +43,6 @@ #ifdef LANGUAGE_UK_UA #include "lang/uk-UA.rc" #endif +#ifdef LANGUAGE_ZH_CN + #include "lang/zh-CN.rc" +#endif From 83fb28ddbffd7f4f1d3e09843ac1fd3567cc8723 Mon Sep 17 00:00:00 2001 From: Ziliang Guo Date: Mon, 5 Aug 2013 17:44:28 +0000 Subject: [PATCH 08/25] [ROSAPPS] Add Chinese translations for ROSAPPS. Translation by Yuntian Zhang. CORE-7348 #resolve svn path=/trunk/; revision=59644 --- reactos/base/applications/rapps/lang/zh-CN.rc | 4 +- reactos/base/applications/rapps/lang/zh-TW.rc | 202 ++++++++++++++++++ reactos/base/applications/rapps/rsrc.rc | 3 + 3 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 reactos/base/applications/rapps/lang/zh-TW.rc diff --git a/reactos/base/applications/rapps/lang/zh-CN.rc b/reactos/base/applications/rapps/lang/zh-CN.rc index 6b12fe62671..57143c9dc3a 100644 --- a/reactos/base/applications/rapps/lang/zh-CN.rc +++ b/reactos/base/applications/rapps/lang/zh-CN.rc @@ -22,7 +22,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "刷新(&R)", ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Update Da&tabase", ID_RESETDB + MENUITEM "更新数据库(&A)", ID_RESETDB END POPUP "帮助" BEGIN @@ -52,7 +52,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "刷新(&R)", ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Update Da&tabase", ID_RESETDB + MENUITEM "更新数据库(&A)", ID_RESETDB END END diff --git a/reactos/base/applications/rapps/lang/zh-TW.rc b/reactos/base/applications/rapps/lang/zh-TW.rc new file mode 100644 index 00000000000..a7e5ac0f7f5 --- /dev/null +++ b/reactos/base/applications/rapps/lang/zh-TW.rc @@ -0,0 +1,202 @@ +/* + * Translated by Song Fuchang (0xfc) + * Converted by OpenCC 0.4.2 + */ + +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL + +IDR_MAINMENU MENU +BEGIN + POPUP "檔案(&F)" + BEGIN + MENUITEM "設定(&S)", ID_SETTINGS + MENUITEM SEPARATOR + MENUITEM "退出(&X)", ID_EXIT + END + POPUP "程式(&P)" + BEGIN + MENUITEM "安裝(&I)", ID_INSTALL + MENUITEM "解除安裝(&U)", ID_UNINSTALL + MENUITEM "修改(&M)", ID_MODIFY + MENUITEM SEPARATOR + MENUITEM "從登錄檔刪除(&E)", ID_REGREMOVE + MENUITEM SEPARATOR + MENUITEM "重新整理(&R)", ID_REFRESH + MENUITEM SEPARATOR + MENUITEM "更新資料庫(&A)", ID_RESETDB + END + POPUP "幫助" + BEGIN + MENUITEM "幫助內容", ID_HELP, GRAYED + MENUITEM "關於", ID_ABOUT + END +END + +IDR_LINKMENU MENU +BEGIN + POPUP "popup" + BEGIN + MENUITEM "在瀏覽器中開啟連結(&O)", ID_OPEN_LINK + MENUITEM "複製連結到剪貼簿(&C)", ID_COPY_LINK + END +END + +IDR_APPLICATIONMENU MENU +BEGIN + POPUP "popup" + BEGIN + MENUITEM "安裝(&I)", ID_INSTALL + MENUITEM "解除安裝(&U)", ID_UNINSTALL + MENUITEM "修改(&M)", ID_MODIFY + MENUITEM SEPARATOR + MENUITEM "從登錄檔刪除(&E)", ID_REGREMOVE + MENUITEM SEPARATOR + MENUITEM "重新整理(&R)", ID_REFRESH + MENUITEM SEPARATOR + MENUITEM "更新資料庫(&A)", ID_RESETDB + END +END + +IDD_SETTINGS_DIALOG DIALOGEX DISCARDABLE 0, 0, 250, 144 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "設定" +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "普通", -1, 4, 2, 240, 61 + AUTOCHECKBOX "儲存視窗位置(&S)", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 + AUTOCHECKBOX "啟動時更新可獲得的程式列表(&U)", IDC_UPDATE_AVLIST, 15, 29, 222, 12 + AUTOCHECKBOX "將程式的安裝和解除安裝記錄到日誌(&L)", IDC_LOG_ENABLED, 15, 46, 219, 12 + + GROUPBOX "正在下載", -1, 4, 65, 240, 51 + LTEXT "下載資料夾:", -1, 16, 75, 100, 9 + EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP + PUSHBUTTON "選擇(&C)", IDC_CHOOSE, 187, 85, 50, 14 + AUTOCHECKBOX "在安裝完程式後刪除安裝程式(&D)", IDC_DEL_AFTER_INSTALL, 16, 100, 218, 12 + + PUSHBUTTON "預設", IDC_DEFAULT_SETTINGS, 8, 124, 60, 14 + PUSHBUTTON "確定", IDOK, 116, 124, 60, 14 + PUSHBUTTON "取消", IDCANCEL, 181, 124, 60, 14 +END + +IDD_INSTALL_DIALOG DIALOGEX DISCARDABLE 0, 0, 216, 97 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "安裝程式" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "...", IDC_INSTALL_TEXT, 4, 5, 209, 35 + + AUTORADIOBUTTON "從存儲裝置安裝 (CD 或 DVD)(&I)", IDC_CD_INSTALL, 10, 46, 197, 11, WS_GROUP + AUTORADIOBUTTON "下載並安裝(&D)", IDC_DOWNLOAD_INSTALL, 10, 59, 197, 11, NOT WS_TABSTOP + + PUSHBUTTON "確定", IDOK, 86, 78, 60, 14 + PUSHBUTTON "取消", IDCANCEL, 150, 78, 60, 14 +END + +IDD_DOWNLOAD_DIALOG DIALOGEX LOADONCALL MOVEABLE DISCARDABLE 0, 0, 220, 76 +STYLE DS_SHELLFONT | DS_CENTER | WS_BORDER | WS_CAPTION | WS_POPUP | WS_SYSMENU | WS_VISIBLE +CAPTION "正在下載..." +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Progress1", IDC_DOWNLOAD_PROGRESS, "msctls_progress32", WS_BORDER | PBS_SMOOTH, 10, 10, 200, 12 + LTEXT "", IDC_DOWNLOAD_STATUS, 10, 30, 200, 10, SS_CENTER + PUSHBUTTON "取消", IDCANCEL, 85, 58, 50, 15, WS_GROUP | WS_TABSTOP +END + +IDD_ABOUT_DIALOG DIALOGEX 22, 16, 190, 66 +STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +CAPTION "關於" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "ReactOS 程式管理器 版權所有 (C) 2009\n作者 Dmitry Chapyshev (dmitry@reactos.org)", IDC_STATIC, 48, 7, 130, 39 + PUSHBUTTON "關閉", IDOK, 133, 46, 50, 14 + ICON IDI_MAIN, IDC_STATIC, 10, 10, 7, 30 +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TOOLTIP_INSTALL "安裝" + IDS_TOOLTIP_UNINSTALL "解除安裝" + IDS_TOOLTIP_MODIFY "修改" + IDS_TOOLTIP_SETTINGS "設定" + IDS_TOOLTIP_REFRESH "重新整理" + IDS_TOOLTIP_EXIT "退出" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_NAME "名稱" + IDS_APP_INST_VERSION "版本" + IDS_APP_DESCRIPTION "描述" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_INFO_VERSION "版本:" + IDS_INFO_DESCRIPTION "描述:" + IDS_INFO_PUBLISHER "\n釋出者:" + IDS_INFO_HELPLINK "\n幫助連結:" + IDS_INFO_HELPPHONE "\n幫助電話:" + IDS_INFO_README "\n必讀:" + IDS_INFO_REGOWNER "\n註冊所有者:" + IDS_INFO_PRODUCTID "\n產品 ID:" + IDS_INFO_CONTACT "\n聯繫方式:" + IDS_INFO_UPDATEINFO "\n更新資訊:" + IDS_INFO_INFOABOUT "\n關於資訊:" + IDS_INFO_COMMENTS "\n註釋:" + IDS_INFO_INSTLOCATION "\n安裝位置:" + IDS_INFO_INSTALLSRC "\n安裝源:" + IDS_INFO_UNINSTALLSTR "\n解除安裝字元串:" + IDS_INFO_MODIFYPATH "\n修改路徑:" + IDS_INFO_INSTALLDATE "\n安裝日期:" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_AINFO_VERSION "\n版本:" + IDS_AINFO_DESCRIPTION "\n描述:" + IDS_AINFO_SIZE "\n大小:" + IDS_AINFO_URLSITE "\n主頁:" + IDS_AINFO_LICENCE "\n協議:" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_CAT_AUDIO "音訊" + IDS_CAT_DEVEL "開發" + IDS_CAT_DRIVERS "驅動程式" + IDS_CAT_EDU "教育與娛樂" + IDS_CAT_ENGINEER "工程" + IDS_CAT_FINANCE "經濟" + IDS_CAT_GAMES "遊戲與娛樂" + IDS_CAT_GRAPHICS "圖形" + IDS_CAT_INTERNET "Internet 與網路" + IDS_CAT_LIBS "庫" + IDS_CAT_OFFICE "辦公" + IDS_CAT_OTHER "其他" + IDS_CAT_SCIENCE "科學" + IDS_CAT_TOOLS "工具" + IDS_CAT_VIDEO "視訊" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APPTITLE "ReactOS 程式管理器" + IDS_SEARCH_TEXT "搜索..." + IDS_INSTALL "安裝" + IDS_UNINSTALL "解除安裝" + IDS_MODIFY "修改" + IDS_APPS_COUNT "程式個數:%d" + IDS_WELCOME_TITLE "歡迎來到 ReactOS 程式管理器!\n\n" + IDS_WELCOME_TEXT "從左欄選擇一個類別,然後選擇要安裝或解除安裝的程式。\nReactOS 網站:" + IDS_WELCOME_URL "http://www.reactos.org" + IDS_INSTALLED "已安裝" + IDS_AVAILABLEFORINST "可安裝" + IDS_UPDATES "更新" + IDS_APPLICATIONS "應用程式" + IDS_CHOOSE_FOLDER_TEXT "請選擇用來儲存下載檔案的資料夾:" + IDS_CHOOSE_FOLDER_ERROR "您選擇的資料夾不存在。創建嗎?" + IDS_USER_NOT_ADMIN "您必須以管理員許可權啟動 ""ReactOS 程式管理器""!" + IDS_APP_REG_REMOVE "您確定要從登錄檔刪除該程式的資料嗎?" + IDS_INFORMATION "資訊" + IDS_UNABLE_TO_REMOVE "無法從登錄檔刪除該程式的資料!" +END diff --git a/reactos/base/applications/rapps/rsrc.rc b/reactos/base/applications/rapps/rsrc.rc index e28ae42a0fd..5293299d4d4 100644 --- a/reactos/base/applications/rapps/rsrc.rc +++ b/reactos/base/applications/rapps/rsrc.rc @@ -56,3 +56,6 @@ #ifdef LANGUAGE_ZH_CN #include "lang/zh-CN.rc" #endif +#ifdef LANGUAGE_ZH_TW + #include "lang/zh-TW.rc" +#endif \ No newline at end of file From c64a17b8dc003ae9ffc8b6605e0a7dcaba8a5168 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 5 Aug 2013 17:57:22 +0000 Subject: [PATCH 09/25] [RAPPS] * Fix the MSVC build. svn path=/trunk/; revision=59645 --- reactos/base/applications/rapps/rsrc.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/applications/rapps/rsrc.rc b/reactos/base/applications/rapps/rsrc.rc index 5293299d4d4..da610c3cd60 100644 --- a/reactos/base/applications/rapps/rsrc.rc +++ b/reactos/base/applications/rapps/rsrc.rc @@ -58,4 +58,4 @@ #endif #ifdef LANGUAGE_ZH_TW #include "lang/zh-TW.rc" -#endif \ No newline at end of file +#endif From ce6c0a9ea5f523d66cc0eab1bdd45ac73ab462b4 Mon Sep 17 00:00:00 2001 From: Ziliang Guo Date: Mon, 5 Aug 2013 18:05:41 +0000 Subject: [PATCH 10/25] [RAPPS] Update Media Player Classic Home Cinema URL as per the request of a MPC dev. svn path=/trunk/; revision=59646 --- reactos/base/applications/rapps/rapps/mpc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/applications/rapps/rapps/mpc.txt b/reactos/base/applications/rapps/rapps/mpc.txt index ee7be799fdf..155f141f9d7 100644 --- a/reactos/base/applications/rapps/rapps/mpc.txt +++ b/reactos/base/applications/rapps/rapps/mpc.txt @@ -7,7 +7,7 @@ Licence = GPL Description = A media player. Size = 7.08MB Category = 1 -URLSite = http://mpc-hc.sourceforge.net/ +URLSite = http://mpc-hc.org/ URLDownload = http://garr.dl.sourceforge.net/project/mpc-hc/MPC%20HomeCinema%20-%20Win32/MPC-HC_v1.6.8_x86/MPC-HC.1.6.8.x86.exe CDPath = none From f9c1de4baa3531fd2aa715faf41a229251c82bea Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 5 Aug 2013 18:33:52 +0000 Subject: [PATCH 11/25] [KERNEL32]: Parsing fixes svn path=/trunk/; revision=59647 --- reactos/dll/win32/kernel32/client/proc.c | 91 ++++++++++++------------ 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index 23f059a338e..384a4e1bcae 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -2291,7 +2291,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, SECTION_IMAGE_INFORMATION ImageInformation; IO_STATUS_BLOCK IoStatusBlock; CLIENT_ID ClientId; - ULONG NoWindow, RegionSize, StackSize, ImageMachine, dwErrCode, Flags; + ULONG NoWindow, RegionSize, StackSize, ImageMachine, ErrorCode, Flags; ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse; ULONG_PTR ErrorParameters[2]; BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege; @@ -2320,14 +2320,14 @@ CreateProcessInternalW(IN HANDLE hUserToken, // PCHAR pcScan; SIZE_T n; - WCHAR TempChar; + WCHAR SaveChar; ULONG Length, CurdirLength, CmdQuoteLength; ULONG CmdLineLength, ResultSize; PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory; - PWCHAR TempNull, WhiteScan, NameBuffer, SearchPath, DebuggerCmdLine; + PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine; ANSI_STRING AnsiEnv; UNICODE_STRING UnicodeEnv, PathName; - BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName; + BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName, HasQuotes; // // Variables used for Fusion/SxS (Side-by-Side Assemblies) @@ -2405,13 +2405,13 @@ CreateProcessInternalW(IN HANDLE hUserToken, DebuggerCmdLine = NULL; PathBuffer = NULL; SearchPath = NULL; - TempNull = 0; + NullBuffer = 0; FreeBuffer = NULL; NameBuffer = NULL; CurrentDirectory = NULL; FilePart = NULL; DebuggerString.Buffer = NULL; - QuotesNeeded = FALSE; + HasQuotes = FALSE; QuotedCmdLine = NULL; /* Zero out initial VDM state */ @@ -2624,7 +2624,7 @@ AppNameRetry: } /* Set the initial parsing state. This code can loop -- don't move this! */ - dwErrCode = FALSE; + ErrorCode = 0; SearchRetry = TRUE; QuotesNeeded = FALSE; CmdLineIsAppName = FALSE; @@ -2647,29 +2647,29 @@ AppNameRetry: } /* Initialize the application name and our parsing parameters */ - lpApplicationName = TempNull = WhiteScan = lpCommandLine; + lpApplicationName = NullBuffer = ScanString = lpCommandLine; /* Check for an initial quote*/ if (*lpCommandLine == L'\"') { /* We found a quote, keep searching for another one */ SearchRetry = FALSE; - WhiteScan++; - lpApplicationName = TempNull = WhiteScan; - while (*WhiteScan) + ScanString++; + lpApplicationName = ScanString; + while (*ScanString) { /* Have we found the terminating quote? */ - if (*WhiteScan == L'\"') + if (*ScanString == L'\"') { /* We're done, get out of here */ - TempNull = WhiteScan; - QuotesNeeded = TRUE; + NullBuffer = ScanString; + HasQuotes = TRUE; break; } /* Keep searching for the quote */ - WhiteScan++; - TempNull = WhiteScan; + ScanString++; + NullBuffer = ScanString; } } else @@ -2677,25 +2677,25 @@ AppNameRetry: StartScan: /* We simply make the application name be the command line*/ lpApplicationName = lpCommandLine; - while (*WhiteScan) + while (*ScanString) { /* Check if it starts with a space or tab */ - if ((*WhiteScan == L' ') || (*WhiteScan == '\t')) + if ((*ScanString == L' ') || (*ScanString == L'\t')) { /* Break out of the search loop */ - TempNull = WhiteScan; + NullBuffer = ScanString; break; } /* Keep searching for a space or tab */ - WhiteScan++; - TempNull = WhiteScan; + ScanString++; + NullBuffer = ScanString; } } /* We have found the end of the application name, terminate it */ - TempChar = *TempNull; - *TempNull = UNICODE_NULL; + SaveChar = *NullBuffer; + *NullBuffer = UNICODE_NULL; /* New iteration -- free any existing saved path */ if (SearchPath) @@ -2746,7 +2746,7 @@ StartScan: if ((Length) && (Length < MAX_PATH)) { /* Everything looks good, restore the name */ - *TempNull = TempChar; + *NullBuffer = SaveChar; lpApplicationName = NameBuffer; } else @@ -2779,23 +2779,23 @@ StartScan: } /* Did we already fail once? */ - if (dwErrCode) + if (ErrorCode) { /* Set the error code */ - SetLastError(dwErrCode); + SetLastError(ErrorCode); } else { /* Not yet, cache it */ - dwErrCode = GetLastError(); + ErrorCode = GetLastError(); } /* Put back the command line */ - *TempNull = TempChar; + *NullBuffer = SaveChar; lpApplicationName = NameBuffer; /* It's possible there's whitespace in the directory name */ - if (!(*WhiteScan) || !(SearchRetry)) + if (!(*ScanString) || !(SearchRetry)) { /* Not the case, give up completely */ Result = FALSE; @@ -2803,11 +2803,12 @@ StartScan: } /* There are spaces, so keep trying the next possibility */ - WhiteScan++; - TempNull = WhiteScan; + ScanString++; + NullBuffer = ScanString; /* We will have to add a quote, since there is a space */ QuotesNeeded = TRUE; + HasQuotes = TRUE; goto StartScan; } } @@ -3437,10 +3438,10 @@ StartScan: } /* Check if we need to account for quotes around the path */ - CmdQuoteLength = CmdLineIsAppName || QuotesNeeded; + CmdQuoteLength = CmdLineIsAppName || HasQuotes; if (!CmdLineIsAppName) { - if (QuotesNeeded) CmdQuoteLength++; + if (HasQuotes) CmdQuoteLength++; } else { @@ -3466,12 +3467,12 @@ StartScan: /* Build it */ wcscpy(AnsiCmdCommand, CMD_STRING); - if ((CmdLineIsAppName) || (QuotesNeeded)) + if ((CmdLineIsAppName) || (HasQuotes)) { wcscat(AnsiCmdCommand, L"\""); } wcscat(AnsiCmdCommand, lpCommandLine); - if ((CmdLineIsAppName) || (QuotesNeeded)) + if ((CmdLineIsAppName) || (HasQuotes)) { wcscat(AnsiCmdCommand, L"\""); } @@ -4062,8 +4063,8 @@ StartScan: /* Allocate our buffer, plus enough space for quotes and a NULL */ QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(), 0, - wcslen(lpCommandLine) * sizeof(WCHAR) + - 2 * sizeof(L'\"') + sizeof(UNICODE_NULL)); + (wcslen(lpCommandLine) * sizeof(WCHAR)) + + (2 * sizeof(L'\"') + sizeof(UNICODE_NULL))); if (QuotedCmdLine) { /* Copy the first quote */ @@ -4072,8 +4073,8 @@ StartScan: /* Save the current null-character */ if (QuotesNeeded) { - TempChar = *TempNull; - *TempNull = UNICODE_NULL; + SaveChar = *NullBuffer; + *NullBuffer = UNICODE_NULL; } /* Copy the command line and the final quote */ @@ -4083,8 +4084,8 @@ StartScan: /* Copy the null-char back */ if (QuotesNeeded) { - *TempNull = TempChar; - wcscat(QuotedCmdLine, TempNull); + *NullBuffer = SaveChar; + wcscat(QuotedCmdLine, NullBuffer); } } else @@ -4095,17 +4096,19 @@ StartScan: } } - /* Reserve the first 1MB if needed */ + /* Use isolation if needed */ if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1; + /* Set the new command-line if needed */ + if ((QuotesNeeded) || (CmdLineIsAppName)) lpCommandLine = QuotedCmdLine; + /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */ Result = BasePushProcessParameters(ParameterFlags, ProcessHandle, RemotePeb, lpApplicationName, CurrentDirectory, - ((QuotesNeeded) || (CmdLineIsAppName)) ? - QuotedCmdLine : lpCommandLine, + lpCommandLine, lpEnvironment, &StartupInfo, dwCreationFlags | NoWindow, From 6568f7df16f6014db74ac4db9c566fa9e7f72da8 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 6 Aug 2013 01:12:08 +0000 Subject: [PATCH 12/25] [HIVES]: Add "System Reserved" and "EMS" group types. [TXTSETUP]: Add sacdrv.sys to the list of setup drivers. [CMAKELISTS]: Add sac/sacdrv/sacmsg to the build. [SACMSG]: Update some messages to give them identifiers. [SACDRV]: Reformat almost the entire driver to ReactOS standards. [SACDRV]: Implement about 50% of the driver, including most of the Channel Manager, Command Manager and Raw Channel Support. Comment and cleanup all of the old code that was there before. This is WIP -- it will only activate if you attempt to enable EMS. EMS/SAC support should be very helpful for Thorium Core/ARM port. svn path=/trunk/; revision=59649 --- reactos/boot/bootdata/hivesys.inf | 9 + reactos/boot/bootdata/txtsetup.sif | 1 + reactos/drivers/CMakeLists.txt | 1 + reactos/drivers/sac/CMakeLists.txt | 2 + reactos/drivers/sac/driver/CMakeLists.txt | 19 + reactos/drivers/sac/driver/chanmgr.c | 765 +++++++++++-- reactos/drivers/sac/driver/channel.c | 710 ++++++++---- reactos/drivers/sac/driver/concmd.c | 81 +- reactos/drivers/sac/driver/conmgr.c | 644 ++++++++--- reactos/drivers/sac/driver/data.c | 504 ++++++++- reactos/drivers/sac/driver/dispatch.c | 102 +- reactos/drivers/sac/driver/init.c | 152 +-- reactos/drivers/sac/driver/memory.c | 235 ++-- reactos/drivers/sac/driver/rawchan.c | 388 +++++-- reactos/drivers/sac/driver/sacdrv.h | 1236 ++++++++++++++++----- reactos/drivers/sac/driver/sacdrv.rc | 2 +- reactos/drivers/sac/driver/util.c | 902 ++++++++++++--- reactos/include/reactos/mc/CMakeLists.txt | 3 +- reactos/include/reactos/mc/sacmsg.mc | 26 +- 19 files changed, 4468 insertions(+), 1314 deletions(-) create mode 100644 reactos/drivers/sac/CMakeLists.txt create mode 100644 reactos/drivers/sac/driver/CMakeLists.txt diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index b027a70a8ce..5c5f94e0b4e 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -1149,6 +1149,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\SecurityProviders\SaslProfiles",,0x000000 ; Service groups HKLM,"SYSTEM\CurrentControlSet\Control\ServiceGroupOrder","List",0x00010000, \ + "System Reserved", \ + "EMS", \ "Boot Bus Extender", \ "System Bus Extender", \ "SCSI Miniport", \ @@ -1342,6 +1344,13 @@ HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Start",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Type",0x00010001,0x00000020 HKLM,"SYSTEM\CurrentControlSet\Services\DHCP\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\dhcpcsvc.dll" +; EMS Serial Administration Console Driver +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Group",0x00000000,"EMS" +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","ImagePath",0x00020000,"system32\drivers\sacdrv.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Start",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Type",0x00010001,0x00000001 + ; Event logging service HKLM,"SYSTEM\CurrentControlSet\Services\EventLog",,0x00000010 HKLM,"SYSTEM\CurrentControlSet\Services\EventLog","DisplayName",0x00000000,"Event Logger" diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index b34c51ef883..d2675d94f39 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -18,6 +18,7 @@ FreeSysPartDiskSpace=350 [SourceDisksFiles] acpi.sys=,,,,,,,,,,,,4 nmidebug.sys=,,,,,,x,,,,,,4 +sacdrv.sys=,,,,,,x,,,,,,4 uniata.sys=,,,,,,x,,,,,,4 buslogic.sys=,,,,,,x,,,,,,4 blue.sys=,,,,,,x,,,,,,4 diff --git a/reactos/drivers/CMakeLists.txt b/reactos/drivers/CMakeLists.txt index fcfaa9396d8..be7f2a02b76 100644 --- a/reactos/drivers/CMakeLists.txt +++ b/reactos/drivers/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(input) add_subdirectory(ksfilter) add_subdirectory(network) add_subdirectory(parallel) +add_subdirectory(sac) add_subdirectory(serial) add_subdirectory(setup) add_subdirectory(storage) diff --git a/reactos/drivers/sac/CMakeLists.txt b/reactos/drivers/sac/CMakeLists.txt new file mode 100644 index 00000000000..987710ae04a --- /dev/null +++ b/reactos/drivers/sac/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(driver) diff --git a/reactos/drivers/sac/driver/CMakeLists.txt b/reactos/drivers/sac/driver/CMakeLists.txt new file mode 100644 index 00000000000..187402740c5 --- /dev/null +++ b/reactos/drivers/sac/driver/CMakeLists.txt @@ -0,0 +1,19 @@ + +list(APPEND SOURCE + chanmgr.c + channel.c + cmdchan.c + concmd.c + conmgr.c + data.c + dispatch.c + init.c + memory.c + rawchan.c + util.c + vtutf8chan.c) + +add_library(sacdrv SHARED ${SOURCE} sacdrv.rc) +set_module_type(sacdrv kernelmodedriver) +add_importlibs(sacdrv ntoskrnl hal) +add_cd_file(TARGET sacdrv DESTINATION reactos/system32/drivers NO_CAB FOR all) diff --git a/reactos/drivers/sac/driver/chanmgr.c b/reactos/drivers/sac/driver/chanmgr.c index 1a655d92c02..bf65042a3ee 100644 --- a/reactos/drivers/sac/driver/chanmgr.c +++ b/reactos/drivers/sac/driver/chanmgr.c @@ -1,176 +1,717 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/chanmgr.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/chanmgr.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +SAC_CHANNEL_LOCK ChannelCreateLock; +BOOLEAN ChannelCreateEnabled; +PSAC_CHANNEL ChannelArray[SAC_MAX_CHANNELS]; +LONG ChannelRefCount[SAC_MAX_CHANNELS]; +LONG ChannelReaped[SAC_MAX_CHANNELS]; +SAC_CHANNEL_LOCK ChannelSlotLock[SAC_MAX_CHANNELS]; +LONG CurrentChannelRefCount; +KMUTEX CurrentChannelLock; -NTSTATUS -ChanMgrInitialize( - VOID - ) +/* FUNCTIONS *****************************************************************/ + +#define MAX_REF_COUNT 100 + +#define CHANNEL_SLOT_IS_IN_USE(x) (ChannelRefCount[(x)] > 0) + +FORCEINLINE +PSAC_CHANNEL +ChannelFromIndex(IN ULONG Index) { - return STATUS_NOT_IMPLEMENTED; + return ChannelArray[Index]; } -NTSTATUS -ChanMgrGetChannelIndex( - IN PSAC_CHANNEL Channel, - IN PULONG ChannelIndex - ) +FORCEINLINE +LONG +ChannelGetReferenceCount(IN LONG Index) { - return STATUS_NOT_IMPLEMENTED; + return ChannelRefCount[Index]; } -NTSTATUS -ChanMgrReleaseChannel( - IN PSAC_CHANNEL Channel - ) +FORCEINLINE +LONG +ChannelReferenceByIndex(IN LONG Index) { - return STATUS_NOT_IMPLEMENTED; + if (ChannelGetReferenceCount(Index) > 0) + { + ASSERT(ChannelRefCount[Index] <= MAX_REF_COUNT); + ASSERT(ChannelRefCount[Index] >= 1); + _InterlockedIncrement(&ChannelRefCount[Index]); + ASSERT(ChannelRefCount[Index] <= MAX_REF_COUNT); + ASSERT(ChannelRefCount[Index] >= 2); + } + + return ChannelGetReferenceCount(Index); } -NTSTATUS -ChanMgrGetByHandle( - IN PSAC_CHANNEL_ID ChannelId, - OUT PSAC_CHANNEL pChannel - ) +FORCEINLINE +LONG +ChannelReferenceByIndexWithLock(IN LONG Index) { - return STATUS_NOT_IMPLEMENTED; + LONG RefCount; + + ChannelSlotLock(Index); + RefCount = ChannelReferenceByIndex(Index); + ChannelSlotUnlock(Index); + return RefCount; } -NTSTATUS -ChanMgrGetByHandleAndFileObject( - IN PSAC_CHANNEL_ID ChannelId, - IN PFILE_OBJECT FileObject, - OUT PSAC_CHANNEL pChannel - ) +FORCEINLINE +LONG +ChannelDereferenceByIndex(IN LONG Index) { - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChanMgrGetChannelByName( - IN PWCHAR Name, - OUT PSAC_CHANNEL pChannel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChanMgrGetByIndex( - IN ULONG TargetIndex, - IN PSAC_CHANNEL *TargetChannel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChanMgrGetNextActiveChannel( - IN PSAC_CHANNEL CurrentChannel, - IN PULONG TargetIndex, - OUT PSAC_CHANNEL *TargetChannel - ) -{ - return STATUS_NOT_IMPLEMENTED; + ASSERT(ChannelGetReferenceCount(Index) <= MAX_REF_COUNT); + ASSERT(ChannelGetReferenceCount(Index) > 1); + _InterlockedDecrement(&ChannelRefCount[Index]); + ASSERT(ChannelGetReferenceCount(Index) >= 1); + return ChannelGetReferenceCount(Index); } +FORCEINLINE VOID -ChanMgrChannelDestroy( - IN PSAC_CHANNEL Channel - ) +ChannelDereferenceByIndexWithLock(IN LONG Index) { + ChannelSlotLock(Index); + ChannelDereferenceByIndex(Index); + ChannelSlotUnlock(Index); +} +FORCEINLINE +VOID +ChannelDereferenceToZeroByIndex(IN LONG Index) +{ + ASSERT(ChannelGetReferenceCount(Index) == 1); + ASSERT(ChannelIsActive(ChannelFromIndex(Index)) == FALSE); + _InterlockedExchange(&ChannelRefCount[Index], 0); +} + +FORCEINLINE +VOID +ChannelReferenceToOneByIndex(IN LONG Index) +{ + ASSERT(ChannelGetReferenceCount(Index) == 0); + _InterlockedExchange(&ChannelRefCount[Index], 1); +} + +FORCEINLINE +VOID +ChannelReferenceToOneByIndexWithLock(IN LONG Index) +{ + ChannelSlotLock(Index); + ASSERT(ChannelGetReferenceCount((Index)) == 1); + _InterlockedExchange(&ChannelRefCount[Index], 1); + ChannelSlotUnlock(Index); } NTSTATUS -ChanMgrCloseChannel( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChanMgrInitialize(VOID) { - return STATUS_NOT_IMPLEMENTED; + ULONG i; + + /* Initialize the channel lock */ + SacInitializeLock(&ChannelCreateLock); + ChannelCreateEnabled = TRUE; + + /* Loop through the channel arrays */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Clear and initialize their locks */ + ChannelArray[i] = NULL; + SacInitializeLock(&ChannelSlotLock[i]); + + /* Clear their statuses and reference counts */ + _InterlockedExchange(&ChannelRefCount[i], 0); + _InterlockedExchange(&ChannelReaped[i], 1); + } + + /* All good */ + return STATUS_SUCCESS; } NTSTATUS -ChanMgrReapChannel( - IN ULONG ChannelIndex - ) +NTAPI +ChanMgrShutdown(VOID) { - return STATUS_NOT_IMPLEMENTED; + /* FIXME: TODO */ + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -ChanMgrReapChannels( - VOID - ) +NTAPI +ChanMgrGetChannelByName(IN PWCHAR Name, + OUT PSAC_CHANNEL* Channel) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status, Status1; + ULONG i; + PSAC_CHANNEL CurrentChannel; + PWCHAR ChannelName; + BOOLEAN Found; + CHECK_PARAMETER1(Name); + CHECK_PARAMETER2(Channel); + + /* Assume failure */ + *Channel = NULL; + Status = STATUS_NOT_FOUND; + + /* Loop through all channels */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Reference this one and check if it's valid */ + if (ChannelReferenceByIndexWithLock(i) > 0) + { + /* All good, grab it */ + CurrentChannel = ChannelFromIndex(i); + ASSERT(CurrentChannel != NULL); + + /* Get its name */ + Status1 = ChannelGetName(CurrentChannel, &ChannelName); + ASSERT(NT_SUCCESS(Status1)); + + /* Check if this is the name that was passed in */ + Found = wcsicmp(Name, ChannelName); + SacFreePool(ChannelName); + if (Found) + { + /* We found it, return it (with a reference held) */ + *Channel = CurrentChannel; + return STATUS_SUCCESS; + } + + /* Not the one we want, dereference this one and keep going */ + ChannelDereferenceByIndexWithLock(i); + } + } + + /* No channels with this name were found */ + return Status; } NTSTATUS -ChanMgrGetChannelCount( - OUT PULONG ChannelCount - ) +NTAPI +ChanMgrGetByHandle(IN SAC_CHANNEL_ID ChannelId, + OUT PSAC_CHANNEL* TargetChannel) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + ULONG i; + PSAC_CHANNEL Channel; + CHECK_PARAMETER2(TargetChannel); + + /* Assume failure */ + *TargetChannel = NULL; + Status = STATUS_NOT_FOUND; + + /* Loop through all channels */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Reference this one and check if it's valid */ + if (ChannelReferenceByIndexWithLock(i) > 0) + { + /* All good, grab it */ + Channel = ChannelFromIndex(i); + ASSERT(Channel != NULL); + + /* Check if the channel ID matches */ + if (ChannelIsEqual(Channel, &ChannelId)) + { + /* We found it, return it (with a reference held) */ + *TargetChannel = Channel; + return STATUS_SUCCESS; + } + + /* Not the one we want, dereference this one and keep going */ + ChannelDereferenceByIndexWithLock(i); + } + } + + /* No channels with this ID were found */ + return Status; } NTSTATUS -ChanMgrIsFull( - OUT PBOOLEAN IsFull - ) +NTAPI +ChanMgrReleaseChannel(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; -} + LONG Index; + ULONG RefCount; + PSAC_CHANNEL ThisChannel; + CHECK_PARAMETER(Channel); -NTSTATUS -ChanMgrShutdown( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; + /* Get the index of the channel */ + Index = ChannelGetIndex(Channel); + + /* Drop a reference -- there should still be at least the keepalive left */ + ChannelSlotLock(Index); + RefCount = ChannelDereferenceByIndex(Index); + ASSERT(RefCount > 0); + + /* Do we only have the keep-alive left, and the channel is dead? */ + if ((RefCount == 1) && !(ChannelIsActive(Channel))) + { + /* Check if the ??? flag is set, or if there's no output data */ + ThisChannel = ChannelFromIndex(Index); + if (!(ThisChannel->Flags & 1)) + { + /* Nope, we can wipe the references and get rid of it */ + ChannelDereferenceToZeroByIndex(Index); + } + else if (!ThisChannel->ChannelHasNewOBufferData) + { + /* No data, we can wipe the references and get rid of it */ + ChannelDereferenceToZeroByIndex(Index); + } + } + + /* We're done, we can unlock the slot now */ + ChannelSlotUnlock(Index); + return STATUS_SUCCESS; } BOOLEAN -ChanMgrIsUniqueName( - IN PWCHAR ChannelName - ) +NTAPI +ChanMgrIsUniqueName(IN PWCHAR ChannelName) { - return FALSE; + NTSTATUS Status; + BOOLEAN IsUnique = FALSE; + PSAC_CHANNEL Channel; + + /* Check if a channel with this name already exists */ + Status = ChanMgrGetChannelByName(ChannelName, &Channel); + if (Status == STATUS_NOT_FOUND) IsUnique = TRUE; + + /* If one did, dereference it, all we wanted was to check uniqueness */ + if (NT_SUCCESS(Status)) ChanMgrReleaseChannel(Channel); + + /* Return if one was found or not */ + return IsUnique; } NTSTATUS -ChanMgrGenerateUniqueCmdName( - IN PWCHAR ChannelName - ) +NTAPI +ChanMgrReapChannel(IN ULONG ChannelIndex) { - return STATUS_NOT_IMPLEMENTED; + /* FIXME: TODO */ + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -ChanMgrCreateChannel( - OUT PSAC_CHANNEL *Channel, - IN PSAC_CHANNEL_ATTRIBUTES Attributes - ) +NTAPI +ChanMgrReapChannels(VOID) { - return STATUS_NOT_IMPLEMENTED; + ULONG i; + NTSTATUS Status = STATUS_SUCCESS; + + /* Loop all the channels */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Lock this index and see if the channel was reaped */ + ChannelSlotLock(i); + if (!ChannelReaped[i]) + { + /* It was not reaped yet, so a channel should still be here */ + ASSERT(ChannelFromIndex(i) != NULL); + if (ChannelGetReferenceCount(i) <= 0) + { + /* The channel has no more references, so clear the buffer flags */ + _InterlockedExchange(&ChannelArray[i]->ChannelHasNewIBufferData, 0); + _InterlockedExchange(&ChannelArray[i]->ChannelHasNewOBufferData, 0); + + /* And reap it */ + Status = ChanMgrReapChannel(i); + } + } + + /* Release the lock, and move on unless reaping failed */ + ChannelSlotUnlock(i); + if (!NT_SUCCESS(Status)) break; + } + + /* Return reaping status */ + return Status; } NTSTATUS -ChanMgrCloseChannelsWithFileObject( - IN PFILE_OBJECT FileObject - ) +NTAPI +ChanMgrCreateChannel(OUT PSAC_CHANNEL *Channel, + IN PSAC_CHANNEL_ATTRIBUTES Attributes) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + PSAC_CHANNEL NewChannel; + SAC_CHANNEL_ID ChanId; + ULONG i; + CHECK_PARAMETER(Channel); + CHECK_PARAMETER2(Attributes); + + /* No other channel create attempts can happen */ + ChannelLockCreates(); + + /* Is the channel manager initialized? */ + if (ChannelCreateEnabled) + { + /* Nope, bail out */ + Status = STATUS_UNSUCCESSFUL; + goto ReturnStatus; + } + + /* Reap any zombie channels */ + Status = ChanMgrReapChannels(); + if (!NT_SUCCESS(Status)) + { + /* Bail out on error */ + Status = STATUS_UNSUCCESSFUL; + goto ReturnStatus; + } + + /* Check if we already have a channel with this name */ + if (!ChanMgrIsUniqueName(Attributes->NameBuffer)) + { + /* We do, fail */ + Status = STATUS_DUPLICATE_NAME; + goto ReturnStatus; + } + + /* Allocate this channel */ + NewChannel = SacAllocatePool(sizeof(SAC_CHANNEL), CHANNEL_BLOCK_TAG); + CHECK_PARAMETER_WITH_STATUS(NewChannel, STATUS_NO_MEMORY); // bug + RtlZeroMemory(NewChannel, sizeof(SAC_CHANNEL)); + + /* Loop channel slots */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Find a free spot for it */ + if (ChannelReaped[i]) + { + /* Free slot found, attempt to use it */ + ASSERT(!CHANNEL_SLOT_IS_IN_USE(i)); + _InterlockedCompareExchangePointer((void* volatile*)&ChannelArray[i], NewChannel, NULL); + if (ChannelArray[i] == NewChannel) break; + } + } + + /* Did we not find a single free slot? */ + if (i == SAC_MAX_CHANNELS) + { + /* Bail out */ + Status = STATUS_UNSUCCESSFUL; + goto ReturnStatus; + } + + /* Create an ID for this channel */ + RtlZeroMemory(&ChanId, sizeof(ChanId)); + Status = ExUuidCreate(&ChanId.ChannelGuid); + if (!NT_SUCCESS(Status)) + { + /* Bail out if we couldn't */ + SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed to get GUID\n"); + goto ReturnStatus; + } + + /* Now create the channel proper */ + Status = ChannelCreate(NewChannel, Attributes, ChanId); + if (NT_SUCCESS(Status)) + { + /* Set the channel index */ + _InterlockedExchange(&NewChannel->Index, i); + + /* Add the initial reference to the channel */ + ChannelReferenceToOneByIndexWithLock(i); + + /* Return it to the caller */ + *Channel = NewChannel; + + /* This slot is now occupied */ + ASSERT(ChannelReaped[i] == 1); + _InterlockedExchange(&ChannelReaped[i], 0); + } + else + { + /* We couldn't create it, free the buffer */ + SacFreePool(NewChannel); + } + +ReturnStatus: + /* Return whatever the operation status was */ + ChannelUnlockCreates(); + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGetByHandleAndFileObject(IN SAC_CHANNEL_ID ChannelId, + IN PFILE_OBJECT FileObject, + OUT PSAC_CHANNEL* TargetChannel) +{ + NTSTATUS Status; + PSAC_CHANNEL FoundChannel; + + /* Lookup the channel by ID first */ + Status = ChanMgrGetByHandle(ChannelId, &FoundChannel); + if (NT_SUCCESS(Status)) + { + /* We found it, now check if the file object matches */ + if (FoundChannel->FileObject == FileObject) + { + /* Yep, return success */ + *TargetChannel = FoundChannel; + } + else + { + /* Nope, drop the reference on the channel */ + ChanMgrReleaseChannel(FoundChannel); + + /* And return failure */ + *TargetChannel = NULL; + Status = STATUS_NOT_FOUND; + } + } + + /* Return if we found it or not */ + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGetChannelIndex(IN PSAC_CHANNEL Channel, + IN PLONG ChannelIndex) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(ChannelIndex); + + /* Just return the index of the channel */ + *ChannelIndex = ChannelGetIndex(Channel); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChanMgrGetByIndex(IN LONG TargetIndex, + IN PSAC_CHANNEL* TargetChannel) +{ + NTSTATUS Status; + CHECK_PARAMETER1(TargetIndex < SAC_MAX_CHANNELS); + CHECK_PARAMETER2(TargetChannel); + + /* Assume failure */ + *TargetChannel = NULL; + Status = STATUS_NOT_FOUND; + + /* Reference this one and check if it's valid */ + if (ChannelReferenceByIndexWithLock(TargetIndex) > 0) + { + /* We found it, return it (with a reference held) */ + *TargetChannel = ChannelFromIndex(TargetIndex); + return STATUS_SUCCESS; + } + + /* No channels with this ID were found */ + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGetNextActiveChannel(IN PSAC_CHANNEL CurrentChannel, + IN PULONG TargetIndex, + OUT PSAC_CHANNEL *TargetChannel) +{ + NTSTATUS Status; + ULONG i; + LONG ChannelIndex, StartIndex; + PSAC_CHANNEL FoundChannel; + BOOLEAN ChannelFound; + CHECK_PARAMETER1(CurrentChannel); + CHECK_PARAMETER2(TargetIndex); + CHECK_PARAMETER3(TargetChannel); + + /* Get the current channel index */ + Status = ChanMgrGetChannelIndex(CurrentChannel, &ChannelIndex); + if (!NT_SUCCESS(Status)) return Status; + + /* Assume failure */ + ChannelFound = FALSE; + + /* Loop through all the possible active channels */ + StartIndex = (ChannelIndex + 1) % SAC_MAX_CHANNELS; + for (i = StartIndex; i != StartIndex; i = (i + 1) % SAC_MAX_CHANNELS) + { + /* Get the channel and see if it exists*/ + Status = ChanMgrGetByIndex(i, &FoundChannel); + if (Status != STATUS_NOT_FOUND) + { + /* Bail out if we failed for some reason */ + if (!NT_SUCCESS(Status)) return Status; + + /* It exists -- is it active? Or, does it have output data? */ + if ((ChannelIsActive(FoundChannel)) || + (!(ChannelIsActive(FoundChannel)) && + (FoundChannel->ChannelHasNewOBufferData))) + { + /* It's active or has output data, return with it */ + ChannelFound = TRUE; + break; + } + + /* Drop the reference on this channel and try the next one */ + Status = ChanMgrReleaseChannel(FoundChannel); + if (!NT_SUCCESS(Status)) return Status; + } + } + + /* Check if we successfully found a channel */ + if ((NT_SUCCESS(Status)) && (ChannelFound)) + { + /* Return it and its indexed. Remember we still hold the reference */ + *TargetIndex = i; + *TargetChannel = FoundChannel; + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ChanMgrChannelDestroy(IN PSAC_CHANNEL Channel) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER(ChannelGetReferenceCount(Channel->Index) > 0); + + /* Destroy the channel */ + return Channel->ChannelDestroy(Channel); +} + +NTSTATUS +NTAPI +ChanMgrCloseChannel(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status; + CHECK_PARAMETER(Channel); + + /* Check if the channel is active */ + if (ChannelIsActive(Channel)) + { + /* Yep, close it */ + Status = ChannelClose(Channel); + } + else + { + /* Nothing to do */ + Status = STATUS_ALREADY_DISCONNECTED; + } + + /* Handle the channel close */ + ConMgrHandleEvent(TRUE, Channel, &Status); + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGetChannelCount(OUT PULONG ChannelCount) +{ + ULONG i; + PSAC_CHANNEL Channel; + NTSTATUS Status; + CHECK_PARAMETER(ChannelCount); + + /* Assume no channels */ + *ChannelCount = 0; + + /* Loop every channel */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* See if this one exists */ + Status = ChanMgrGetByIndex(i, &Channel); + if (Status != STATUS_NOT_FOUND) + { + /* Sanity checks*/ + ASSERT(NT_SUCCESS(Status)); + ASSERT(Channel != NULL); + + /* It exists -- is it active? Or, does it have output data? */ + if ((ChannelIsActive(Channel)) || + (!(ChannelIsActive(Channel)) && + (Channel->ChannelHasNewOBufferData))) + { + /* It's active or has output data, increase the count */ + ++*ChannelCount; + break; + } + + /* Drop the reference on this channel and try the next one */ + Status = ChanMgrReleaseChannel(Channel); + if (!NT_SUCCESS(Status)) return Status; + } + else + { + /* Channel doesn't exist, nothing wrong with that, keep going */ + Status = STATUS_SUCCESS; + } + } + + /* We should always succeed if we get here */ + ASSERT(NT_SUCCESS(Status)); + return Status; +} + +NTSTATUS +NTAPI +ChanMgrIsFull(OUT PBOOLEAN IsFull) +{ + NTSTATUS Status; + ULONG Count; + + /* Count the channels */ + Status = ChanMgrGetChannelCount(&Count); + CHECK_PARAMETER(Status == STATUS_SUCCESS); + + /* Return if we hit the limit */ + *IsFull = (Count == SAC_MAX_CHANNELS); + return Status; +} + +NTSTATUS +NTAPI +ChanMgrCloseChannelsWithFileObject(IN PFILE_OBJECT FileObject) +{ + PSAC_CHANNEL Channel; + ULONG i; + NTSTATUS Status; + CHECK_PARAMETER1(FileObject); + + /* Loop all channels */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Try to get this one */ + Status = ChanMgrGetByIndex(i, &Channel); + if (!NT_SUCCESS(Status)) break; + + /* Check if the FO matches, if so, close the channel */ + if (Channel->FileObject == FileObject) ChanMgrCloseChannel(Channel); + + /* Drop the reference and try the next channel(s) */ + Status = ChanMgrReleaseChannel(Channel); + if (!NT_SUCCESS(Status)) break; + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGenerateUniqueCmdName(IN PWCHAR ChannelName) +{ + return STATUS_NOT_IMPLEMENTED; } diff --git a/reactos/drivers/sac/driver/channel.c b/reactos/drivers/sac/driver/channel.c index 154097ebec0..0ee165d7066 100644 --- a/reactos/drivers/sac/driver/channel.c +++ b/reactos/drivers/sac/driver/channel.c @@ -1,318 +1,568 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/channel.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/channel.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ BOOLEAN -ChannelIsValidType( - IN SAC_CHANNEL_TYPE ChannelType - ) +NTAPI +ChannelIsValidType(IN SAC_CHANNEL_TYPE ChannelType) { - return ((ChannelType >= VtUtf8) && (ChannelType <= Raw)); + /* Check if the type is valid */ + return ((ChannelType >= VtUtf8) && (ChannelType <= Raw)); } BOOLEAN -ChannelIsEqual( - IN PSAC_CHANNEL Channel, - IN PSAC_CHANNEL_ID ChannelId - ) +NTAPI +ChannelIsEqual(IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ID ChannelId) { - return IsEqualGUIDAligned( - &Channel->ChannelId.ChannelGuid, - &ChannelId->ChannelGuid); + /* Check if the GUIDs match */ + return IsEqualGUIDAligned(&Channel->ChannelId.ChannelGuid, + &ChannelId->ChannelGuid); } NTSTATUS -ChannelInitializeVTable( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelDereferenceHandles(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER(Channel); + + /* Clear the data event */ + if (Channel->HasNewDataEvent) + { + ChannelUninitializeEvent(Channel, + HasNewDataEvent, + SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT); + } + + /* Clear the close event */ + if (Channel->CloseEvent) + { + ChannelUninitializeEvent(Channel, + CloseEvent, + SAC_CHANNEL_FLAG_CLOSE_EVENT); + } + + /* Clear the lock event */ + if (Channel->LockEvent) + { + ChannelUninitializeEvent(Channel, + LockEvent, + SAC_CHANNEL_FLAG_LOCK_EVENT); + } + + /* Clear the redraw event */ + if (Channel->RedrawEvent) + { + ChannelUninitializeEvent(Channel, + RedrawEvent, + SAC_CHANNEL_FLAG_REDRAW_EVENT); + } + + /* All done */ + return STATUS_SUCCESS; } NTSTATUS -ChannelDereferenceHandles( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelDestroy(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER(Channel); + + /* Same thing as dereferencing all the handles */ + return ChannelDereferenceHandles(Channel); } NTSTATUS -ChannelDestroy( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelOWrite(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize) { - CHECK_PARAMETER(Channel); - - return ChannelDereferenceHandles(Channel); + NTSTATUS Status; + CHECK_PARAMETER3(BufferSize < SAC_OBUFFER_SIZE); + + /* While holding the output lock, write to the output buffer */ + ChannelLockOBuffer(Channel); + Status = Channel->ChannelOutputWrite(Channel, Buffer, BufferSize); + ChannelUnlockOBuffer(Channel); + return Status; } NTSTATUS -ChannelOWrite( - IN PSAC_CHANNEL Channel, - IN PWCHAR Buffer, - IN ULONG BufferSize - ) +NTAPI +ChannelOFlush(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; - - CHECK_PARAMETER3(BufferSize < SAC_OBUFFER_SIZE); + NTSTATUS Status; - ChannelLockOBuffer(Channel); - - Status = Channel->OBufferWrite(Channel, Buffer, BufferSize); - - ChannelUnlockOBuffer(Channel); - - return Status; + /* While holding the output lock, flush to the output buffer */ + ChannelLockOBuffer(Channel); + Status = Channel->ChannelOutputFlush(Channel); + ChannelUnlockOBuffer(Channel); + return Status; } NTSTATUS -ChannelOFlush( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelIWrite(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize) { - NTSTATUS Status; - - ChannelLockOBuffer(Channel); + NTSTATUS Status; - Status = Channel->OBufferFlush(Channel); - - ChannelUnlockOBuffer(Channel); - - return Status; + /* Write into the input buffer while holding the lock */ + ChannelLockIBuffer(Channel); + Status = Channel->ChannelInputWrite(Channel, Buffer, BufferSize); + ChannelUnlockIBuffer(Channel); + return Status; } NTSTATUS -ChannelIWrite( - IN PSAC_CHANNEL Channel, - IN PWCHAR Buffer, - IN ULONG BufferSize - ) +NTAPI +ChannelIRead(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN OUT PULONG ResultBufferSize) { - NTSTATUS Status; + NTSTATUS Status; - ChannelLockIBuffer(Channel); - - Status = Channel->IBufferWrite(Channel, Buffer, BufferSize); - - ChannelUnlockIBuffer(Channel); - - return Status; + /* Read the input buffer while holding the lock */ + ChannelLockIBuffer(Channel); + Status = Channel->ChannelInputRead(Channel, + Buffer, + BufferSize, + ResultBufferSize); + ChannelUnlockIBuffer(Channel); + return Status; } -ULONG -ChannelIRead( - IN PSAC_CHANNEL Channel, - PWCHAR Buffer, - ULONG BufferSize, - OUT PULONG ResultBufferSize - ) +UCHAR +NTAPI +ChannelIReadLast(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; - - ChannelLockIBuffer(Channel); + UCHAR LastChar; - Status = Channel->IBufferRead(Channel, Buffer, BufferSize, ResultBufferSize); - - ChannelUnlockIBuffer(Channel); - - return Status; -} - -NTSTATUS -ChannelIReadLast( - IN PSAC_CHANNEL Channel - ) -{ - NTSTATUS Status; - - ChannelLockIBuffer(Channel); - - Status = Channel->IBufferReadLast(Channel); - - ChannelUnlockIBuffer(Channel); - - return Status; + /* Read the last character while holding the lock */ + ChannelLockIBuffer(Channel); + LastChar = Channel->ChannelInputReadLast(Channel); + ChannelUnlockIBuffer(Channel); + return LastChar; } ULONG -ChannelIBufferLength( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelIBufferLength(IN PSAC_CHANNEL Channel) { - NTSTATUS Length; + ULONG Length; - ChannelLockOBuffer(Channel); - - Length = Channel->IBufferLength(Channel); - - ChannelUnlockOBuffer(Channel); - - return Length; -} - -NTSTATUS -ChannelGetName( - IN PSAC_CHANNEL Channel, - OUT PWCHAR *Name - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelSetName( - IN PSAC_CHANNEL Channel, - IN PWCHAR Name - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelGetDescription( - IN PSAC_CHANNEL Channel, - OUT PWCHAR *Description - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelSetDescription( - IN PSAC_CHANNEL Channel, - IN PWCHAR Description - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelSetStatus( - IN PSAC_CHANNEL Channel, - IN SAC_CHANNEL_STATUS ChannelStatus - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelGetStatus( - IN PSAC_CHANNEL Channel, - OUT PSAC_CHANNEL_STATUS ChannelStatus - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelGetApplicationType( - IN PSAC_CHANNEL Channel, - OUT PGUID ApplicationType - ) -{ - return STATUS_NOT_IMPLEMENTED; + /* Get the input buffer length while holding the lock */ + ChannelLockOBuffer(Channel); + Length = Channel->ChannelInputBufferLength(Channel); + ChannelUnlockOBuffer(Channel); + return Length; } NTSTATUS NTAPI -ChannelSetLockEvent( - IN PSAC_CHANNEL Channel - ) +ChannelSetRedrawEvent(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; - - ChannelSetEvent(Channel, LockEvent); - - return Status; + NTSTATUS Status; + + /* Set the event */ + ChannelSetEvent(Channel, RedrawEvent); + return Status; } NTSTATUS NTAPI -ChannelSetRedrawEvent( - IN PSAC_CHANNEL Channel - ) +ChannelSetLockEvent(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; + NTSTATUS Status; - ChannelSetEvent(Channel, RedrawEvent); - - return Status; + /* Set the event */ + ChannelSetEvent(Channel, LockEvent); + return Status; } NTSTATUS -ChannelClearRedrawEvent( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelClearRedrawEvent(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; - - ChannelClearEvent(Channel, RedrawEvent); - - return Status; + NTSTATUS Status; + + /* Clear the event */ + ChannelClearEvent(Channel, RedrawEvent); + return Status; } NTSTATUS -ChannelHasRedrawEvent( - IN PSAC_CHANNEL Channel, - OUT PBOOLEAN Present - ) +NTAPI +ChannelHasRedrawEvent(IN PSAC_CHANNEL Channel, + OUT PBOOLEAN Present) { - CHECK_PARAMETER1(Channel); - CHECK_PARAMETER2(Present); - - *Present = Channel->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT; - - return STATUS_SUCCESS; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Present); + + /* Return if the flag is set */ + *Present = Channel->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelGetStatus(IN PSAC_CHANNEL Channel, + OUT PSAC_CHANNEL_STATUS ChannelStatus) +{ + CHECK_PARAMETER1(Channel); + + /* Read the status while holding the attribute lock */ + ChannelLockAttributes(Channel); + *ChannelStatus = Channel->ChannelStatus; + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelSetStatus(IN PSAC_CHANNEL Channel, + IN SAC_CHANNEL_STATUS ChannelStatus) +{ + CHECK_PARAMETER1(Channel); + + /* Read the status while holding the attribute lock */ + ChannelLockAttributes(Channel); + Channel->ChannelStatus = ChannelStatus; + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; } BOOLEAN -ChannelIsActive( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelIsActive(IN PSAC_CHANNEL Channel) { - SAC_CHANNEL_STATUS ChannelStatus; + SAC_CHANNEL_STATUS ChannelStatus; + BOOLEAN IsActive; - if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus))) return FALSE; + /* Get the status */ + if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus))) + { + /* We couldn't even do that, assume it's inactive */ + IsActive = FALSE; + } + else + { + /* Check if the status shows activity */ + IsActive = (ChannelStatus == Active); + } - return (ChannelStatus == Active); + /* Return the state */ + return IsActive; } BOOLEAN -ChannelIsClosed( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelIsClosed(IN PSAC_CHANNEL Channel) { - return FALSE; + SAC_CHANNEL_STATUS ChannelStatus; + BOOLEAN IsClosed; + + /* Get the status */ + if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus))) + { + /* We couldn't even do that, assume it's inactive */ + IsClosed = FALSE; + } + else + { + /* Check if the status shows activity */ + IsClosed = ((ChannelStatus == Inactive) && + (Channel->ChannelHasNewOBufferData)); + } + + /* Return the state */ + return IsClosed; } NTSTATUS -ChannelCreate( - IN PSAC_CHANNEL Channel, - IN PSAC_CHANNEL_ATTRIBUTES Attributes, - IN SAC_CHANNEL_ID ChannelId - ) +NTAPI +ChannelGetName(IN PSAC_CHANNEL Channel, + OUT PWCHAR *Name) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Name); + + /* Allocate space to hold the name */ + *Name = SacAllocatePool(sizeof(Channel->NameBuffer), GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(*Name); + + /* Lock the attributes while we copy the name */ + ChannelLockAttributes(Channel); + + /* Copy the name and null-terminate it */ + ASSERT(((wcslen(Channel->NameBuffer) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR))); + wcsncpy(*Name, Channel->NameBuffer, RTL_NUMBER_OF(Channel->NameBuffer)); // bug + (*Name)[SAC_CHANNEL_NAME_SIZE] = UNICODE_NULL; + + /* Release the lock and return */ + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; } NTSTATUS -ChannelClose( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelSetName(IN PSAC_CHANNEL Channel, + IN PWCHAR Name) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Name); + + /* Lock the attributes while we copy the name */ + ChannelLockAttributes(Channel); + + /* Copy the name and null-terminate it */ + ASSERT(((wcslen(Name) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR))); + wcsncpy(Channel->NameBuffer, Name, RTL_NUMBER_OF(Channel->NameBuffer)); // bug + Channel->NameBuffer[SAC_CHANNEL_NAME_SIZE] = UNICODE_NULL; + + /* Release the lock and return */ + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; } + +NTSTATUS +NTAPI +ChannelGetDescription(IN PSAC_CHANNEL Channel, + IN PWCHAR* Description) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Description); + + /* Allocate space to hold the description */ + *Description = SacAllocatePool(sizeof(Channel->DescriptionBuffer), GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(*Description); + + /* Lock the attributes while we copy the name */ + ChannelLockAttributes(Channel); + + /* Copy the name and null-terminate it */ + ASSERT(((wcslen(Channel->DescriptionBuffer) + 1) * sizeof(WCHAR)) <= ((256 + 1) * sizeof(WCHAR))); + wcsncpy(*Description, Channel->DescriptionBuffer, RTL_NUMBER_OF(Channel->DescriptionBuffer)); // bug + (*Description)[SAC_CHANNEL_DESCRIPTION_SIZE] = UNICODE_NULL; + + /* Release the lock and return */ + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelSetDescription(IN PSAC_CHANNEL Channel, + IN PWCHAR Description) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Description); + + /* Lock the attributes while we copy the name */ + ChannelLockAttributes(Channel); + + /* Copy the name and null-terminate it */ + ASSERT(((wcslen(Description) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR))); + wcsncpy(Channel->DescriptionBuffer, Description, RTL_NUMBER_OF(Channel->DescriptionBuffer)); // bug + Channel->DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE] = UNICODE_NULL; + + /* Release the lock and return */ + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelGetApplicationType(IN PSAC_CHANNEL Channel, + OUT PGUID ApplicationType) +{ + CHECK_PARAMETER1(Channel); + + /* Read the application type GUID */ + ChannelLockAttributes(Channel); + *ApplicationType = Channel->ApplicationType; + ChannelUnlockAttributes(Channel); + + /* Always return success */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelInitializeVTable(IN PSAC_CHANNEL Channel) +{ + /* What kind of channel is this? */ + switch (Channel->ChannelType) + { + case VtUtf8: + /* FIXME: TODO */ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; + + case Cmd: + /* FIXME: TODO */ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; + + case Raw: + + /* Setup the calls for a raw channel */ + Channel->ChannelCreate = RawChannelCreate; + Channel->ChannelDestroy = RawChannelDestroy; + Channel->ChannelOutputFlush = RawChannelOFlush; + Channel->ChannelOutputEcho = RawChannelOEcho; + Channel->ChannelOutputWrite = RawChannelOWrite; + Channel->ChannelOutputRead = RawChannelORead; + Channel->ChannelInputWrite = RawChannelIWrite; + Channel->ChannelInputRead = RawChannelIRead; + Channel->ChannelInputReadLast = RawChannelIReadLast; + Channel->ChannelInputBufferIsFull = RawChannelIBufferIsFull; + Channel->ChannelInputBufferLength = RawChannelIBufferLength; + break; + + default: + /* Unsupported channel type */ + return STATUS_INVALID_PARAMETER; + } + + /* If we got here, the channel was supported */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelCreate(IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ATTRIBUTES Attributes, + IN SAC_CHANNEL_ID ChannelId) +{ + NTSTATUS Status; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Attributes); + + /* If a close event is being passed in, it must exist, and vice-versa */ + if (Attributes->Flag & SAC_CHANNEL_FLAG_CLOSE_EVENT) + { + CHECK_PARAMETER(Attributes->CloseEvent != NULL); + } + else + { + CHECK_PARAMETER(Attributes->CloseEvent == NULL); + } + + /* If a new data event is being passed in, it must exist, and vice-versa */ + if (Attributes->Flag & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) + { + CHECK_PARAMETER(Attributes->HasNewDataEvent != NULL); + } + else + { + CHECK_PARAMETER(Attributes->HasNewDataEvent == NULL); + } + + /* If a lock event is being passed in, it must exist, and vice-versa */ + if (Attributes->Flag & SAC_CHANNEL_FLAG_LOCK_EVENT) + { + CHECK_PARAMETER(Attributes->LockEvent != NULL); + } + else + { + CHECK_PARAMETER(Attributes->LockEvent == NULL); + } + + /* If a redraw event is being passed in, it must exist, and vice-versa */ + if (Attributes->Flag & SAC_CHANNEL_FLAG_REDRAW_EVENT) + { + CHECK_PARAMETER(Attributes->RedrawEvent != NULL); + } + else + { + CHECK_PARAMETER(Attributes->RedrawEvent == NULL); + } + + /* Initialize the channel structure */ + RtlZeroMemory(Channel, sizeof(SAC_CHANNEL)); + Channel->ChannelId = ChannelId; + Channel->ChannelType = Attributes->ChannelType; + Channel->Flags = Attributes->Flag; + if (Attributes->Flag & SAC_CHANNEL_FLAG_APPLICATION) + { + Channel->ApplicationType = Attributes->ChannelId; + } + + /* Initialize all the locks and events */ + SacInitializeLock(&Channel->ChannelAttributeLock); + SacInitializeLock(&Channel->ChannelOBufferLock); + SacInitializeLock(&Channel->ChannelIBufferLock); + ChannelInitializeEvent(Channel, Attributes, CloseEvent); + ChannelInitializeEvent(Channel, Attributes, HasNewDataEvent); + ChannelInitializeEvent(Channel, Attributes, LockEvent); + ChannelInitializeEvent(Channel, Attributes, RedrawEvent); + + /* Set the name and description */ + ChannelSetName(Channel, Attributes->NameBuffer); + ChannelSetDescription(Channel, Attributes->DescriptionBuffer); + + /* Initialize the function table for the type of channel this is */ + Status = ChannelInitializeVTable(Channel); + if (!NT_SUCCESS(Status)) + { + /* This is critical */ + SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed to initialize vtable\n"); + goto FailChannel; + } + + /* Now call the channel specific type constructor */ + Status = Channel->ChannelCreate(Channel); + if (!NT_SUCCESS(Status)) + { + /* This is critical */ + SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed channel specific initialization\n"); + goto FailChannel; + } + + /* Finally, mark the channel as active */ + ChannelSetStatus(Channel, Active); + return STATUS_SUCCESS; + +FailChannel: + /* Destroy the channel and return the failure code */ + Channel->ChannelDestroy(Channel); + return Status; +} + +NTSTATUS +NTAPI +ChannelClose(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status; + CHECK_PARAMETER(Channel); + + /* Set the channel inactive */ + ChannelSetStatus(Channel, Inactive); + + /* Set the close event */ + if (Channel->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT) + { + ChannelSetEvent(Channel, CloseEvent); + } + + /* Close all the handles */ + Status = ChannelDereferenceHandles(Channel); + return Status; +} + diff --git a/reactos/drivers/sac/driver/concmd.c b/reactos/drivers/sac/driver/concmd.c index 42b87ca2795..76d6edbfe47 100644 --- a/reactos/drivers/sac/driver/concmd.c +++ b/reactos/drivers/sac/driver/concmd.c @@ -1,18 +1,75 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/concmd.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/concmd.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +PWCHAR GlobalBuffer; +ULONG GlobalBufferSize; + +/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +DoRebootCommand(IN BOOLEAN Reboot) +{ + LARGE_INTEGER Timeout, TickCount; + NTSTATUS Status; + KEVENT Event; + SAC_DBG(1, "SAC DoRebootCommand: Entering.\n"); + + /* Get the current time now, and setup a timeout in 1 second */ + KeQueryTickCount(&TickCount); + Timeout.QuadPart = TickCount.QuadPart / (10000000 / KeQueryTimeIncrement()); + + /* Check if the timeout is small enough */ + if (Timeout.QuadPart < 60 ) + { + /* Show the prompt */ + ConMgrSimpleEventMessage(Reboot ? + SAC_RESTART_PROMPT : SAC_SHUTDOWN_PROMPT, + TRUE); + + /* Do the wait */ + KeInitializeEvent(&Event, SynchronizationEvent, 0); + Timeout.QuadPart = -10000000 * (60 - Timeout.LowPart); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &Timeout); + } + + /* Do a shutdown or a reboot, based on the request */ + Status = NtShutdownSystem(Reboot ? ShutdownReboot : ShutdownPowerOff); + + /* Check if anyone in the command channel already allocated this */ + if (!GlobalBuffer) + { + /* Allocate it */ + GlobalBuffer = SacAllocatePool(PAGE_SIZE, GLOBAL_BLOCK_TAG); + if (!GlobalBuffer) + { + /* We need the global buffer, bail out without it*/ + SacPutSimpleMessage(SAC_OUT_OF_MEMORY_PROMPT); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting (1).\n"); + return; + } + + /* Set the size of the buffer */ + GlobalBufferSize = PAGE_SIZE; + } + + /* We came back from a reboot, this doesn't make sense, tell the user */ + SacPutSimpleMessage(Reboot ? SAC_RESTART_FAIL_PROMPT : SAC_SHUTDOWN_FAIL_PROMPT); + swprintf(GlobalBuffer, GetMessage(SAC_FAIL_PROMPT), Status); + SacPutString(GlobalBuffer); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting.\n"); +} NTSTATUS GetTListInfo( @@ -122,14 +179,6 @@ DoLimitMemoryCommand( } -VOID -DoRebootCommand( - IN BOOLEAN Reboot - ) -{ - -} - VOID DoCrashCommand( VOID diff --git a/reactos/drivers/sac/driver/conmgr.c b/reactos/drivers/sac/driver/conmgr.c index a01819394af..b012cad03f7 100644 --- a/reactos/drivers/sac/driver/conmgr.c +++ b/reactos/drivers/sac/driver/conmgr.c @@ -1,191 +1,541 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/conmgr.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/conmgr.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +DEFINE_GUID(PRIMARY_SAC_CHANNEL_APPLICATION_GUID, + 0x63D02270, + 0x8AA4, + 0x11D5, + 0xBC, 0xCF, 0x80, 0x6D, 0x61, 0x72, 0x69, 0x6F); -NTSTATUS -ConMgrShutdown( - VOID) +LONG CurrentChannelRefCount; +KMUTEX CurrentChannelLock; + +PSAC_CHANNEL CurrentChannel; +PSAC_CHANNEL SacChannel; + +ULONG ExecutePostConsumerCommand; +PSAC_CHANNEL ExecutePostConsumerCommandData; + +/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +ConMgrSerialPortConsumer(VOID) { - return STATUS_NOT_IMPLEMENTED; -} + NTSTATUS Status; + CHAR Char; + SAC_DBG(0x2000, "SAC TimerDpcRoutine: Entering.\n"); //bug -NTSTATUS -ConMgrDisplayFastChannelSwitchingInterface( - IN PSAC_CHANNEL Channel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} + /* Acquire the manager lock and make sure a channel is selected */ + SacAcquireMutexLock(); + ASSERT(CurrentChannel); -NTSTATUS -ConMgrSetCurrentChannel( - IN PSAC_CHANNEL Channel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} + /* Read whatever came off the serial port */ + for (Status = SerialBufferGetChar(&Char); + NT_SUCCESS(Status); + Status = SerialBufferGetChar(&Char)) + { + /* If nothing came through, bail out */ + if (Status == STATUS_NO_DATA_DETECTED) break; + } -NTSTATUS -ConMgrDisplayCurrentChannel( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ConMgrAdvanceCurrentChannel( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -BOOLEAN -ConMgrIsWriteEnabled( - IN PSAC_CHANNEL Channel - ) -{ - return FALSE; + /* We're done, release the lock */ + SacReleaseMutexLock(); + SAC_DBG(0x2000, "SAC TimerDpcRoutine: Exiting.\n"); //bug } VOID -SacPutString( - IN PWCHAR String - ) +NTAPI +ConMgrWorkerProcessEvents(IN PSAC_DEVICE_EXTENSION DeviceExtension) { + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC WorkerProcessEvents: Entering.\n"); -} + /* Enter the main loop */ + while (TRUE) + { + /* Wait for something to do */ + KeWaitForSingleObject(&DeviceExtension->Event, + Executive, + KernelMode, + FALSE, + NULL); -BOOLEAN -SacPutSimpleMessage( - IN ULONG MessageIndex - ) -{ - return FALSE; -} + /* Consume data off the serial port */ + ConMgrSerialPortConsumer(); + switch (ExecutePostConsumerCommand) + { + case 1: + /* A reboot was sent, do it */ + DoRebootCommand(FALSE); + break; -NTSTATUS -ConMgrChannelOWrite( - IN PSAC_CHANNEL Channel, - IN PVOID WriteBuffer - ) -{ - return STATUS_NOT_IMPLEMENTED; -} + case 2: + /* A close was sent, do it */ + ChanMgrCloseChannel(ExecutePostConsumerCommandData); + ChanMgrReleaseChannel(ExecutePostConsumerCommandData); + break; -NTSTATUS -ConMgrGetChannelCloseMessage( - IN PSAC_CHANNEL Channel, - IN NTSTATUS CloseStatus, - OUT PWCHAR OutputBuffer - ) -{ - return STATUS_NOT_IMPLEMENTED; -} + case 3: + /* A shutdown was sent, do it */ + DoRebootCommand(TRUE); + break; + } -NTSTATUS -ConMgrWriteData( - IN PSAC_CHANNEL Channel, - IN PVOID Buffer, - IN ULONG BufferLength - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ConMgrFlushData( - IN PSAC_CHANNEL Channel - ) -{ - return FALSE; -} - -BOOLEAN -ConMgrIsSacChannel( - IN PSAC_CHANNEL Channel - ) -{ - return FALSE; -} - -NTSTATUS -ConMgrInitialize( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ConMgrResetCurrentChannel( - IN BOOLEAN KeepChannel - ) -{ - return STATUS_NOT_IMPLEMENTED; + /* Clear the serial port consumer state */ + ExecutePostConsumerCommand = 0; + ExecutePostConsumerCommandData = NULL; + } } VOID -ConMgrProcessInputLine( - VOID - ) -{ - -} - -VOID -ConMgrEventMessage( - IN PWCHAR EventMessage, - IN BOOLEAN LockHeld - ) +NTAPI +SacPutString(IN PWCHAR String) { + NTSTATUS Status; + /* Write the string on the main SAC channel */ + Status = ChannelOWrite(SacChannel, + (PCHAR)String, + wcslen(String) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC XmlMgrSacPutString: OWrite failed\n"); + } } BOOLEAN -ConMgrSimpleEventMessage( - IN ULONG MessageIndex, - IN BOOLEAN LockHeld - ) +NTAPI +SacPutSimpleMessage(IN ULONG MessageIndex) { - return FALSE; + PWCHAR MessageBuffer; + BOOLEAN Result; + + /* Get the message */ + MessageBuffer = GetMessage(MessageIndex); + if (MessageBuffer) + { + /* Output it */ + SacPutString(MessageBuffer); + Result = TRUE; + } + else + { + Result = FALSE; + } + + /* All done */ + return Result; } NTSTATUS -ConMgrChannelClose( - IN PSAC_CHANNEL Channel - ) +NTAPI +ConMgrDisplayCurrentChannel(VOID) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + BOOLEAN HasRedraw; + + /* Make sure the lock is held */ + SacAssertMutexLockHeld(); + + /* Check if we can redraw */ + Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedraw); + if (NT_SUCCESS(Status)) + { + /* Enable writes */ + _InterlockedExchange(&CurrentChannel->WriteEnabled, 1); + if (HasRedraw) + { + /* If we can redraw, set the event */ + ChannelSetRedrawEvent(CurrentChannel); + } + + /* Flush the output */ + Status = ChannelOFlush(CurrentChannel); + } + + /* All done, return the status */ + return Status; } NTSTATUS -ConMgrHandleEvent( - IN ULONG EventCode, - IN PSAC_CHANNEL Channel, - OUT PVOID Data - ) +NTAPI +ConMgrWriteData(IN PSAC_CHANNEL Channel, + IN PVOID Buffer, + IN ULONG BufferLength) { - return STATUS_NOT_IMPLEMENTED; + ULONG i; + NTSTATUS Status; + LARGE_INTEGER Interval; + + /* Loop up to 32 times */ + for (i = 0; i < 32; i++) + { + /* Attempt sending the data */ + Status = HeadlessDispatch(HeadlessCmdPutData, Buffer, BufferLength, NULL, NULL); + if (Status != STATUS_UNSUCCESSFUL) break; + + /* Sending the data on the port failed, wait a second... */ + Interval.HighPart = -1; + Interval.LowPart = -100000; + KeDelayExecutionThread(KernelMode, FALSE, &Interval); + } + + /* After 32 attempts it should really have worked... */ + ASSERT(NT_SUCCESS(Status)); + return Status; +} + +NTSTATUS +NTAPI +ConMgrFlushData(IN PSAC_CHANNEL Channel) +{ + /* Nothing to do */ + return STATUS_SUCCESS; +} + +BOOLEAN +NTAPI +ConMgrIsSacChannel(IN PSAC_CHANNEL Channel) +{ + /* Check which channel is active */ + return Channel == SacChannel; +} + +BOOLEAN +NTAPI +ConMgrIsWriteEnabled(IN PSAC_CHANNEL Channel) +{ + /* If the current channel is active, allow writes */ + return ChannelIsEqual(Channel, &CurrentChannel->ChannelId); +} + +NTSTATUS +NTAPI +ConMgrInitialize(VOID) +{ + PWCHAR pcwch; + PSAC_CHANNEL FoundChannel; + SAC_CHANNEL_ATTRIBUTES SacChannelAttributes; + NTSTATUS Status; + + /* Initialize the connection manager lock */ + SacInitializeMutexLock(); + SacAcquireMutexLock(); + + /* Setup the attributes for the raw SAC channel */ + RtlZeroMemory(&SacChannelAttributes, sizeof(SacChannelAttributes)); + SacChannelAttributes.ChannelType = Raw; + + /* Get the right name for it */ + pcwch = GetMessage(SAC_CHANNEL_NAME); + ASSERT(pcwch); + wcsncpy(SacChannelAttributes.NameBuffer, pcwch, SAC_CHANNEL_NAME_SIZE); + SacChannelAttributes.NameBuffer[SAC_CHANNEL_NAME_SIZE] = ANSI_NULL; + + /* Get the right description for it */ + pcwch = GetMessage(SAC_CHANNEL_DESCRIPTION); + ASSERT(pcwch); + wcsncpy(SacChannelAttributes.DescriptionBuffer, pcwch, SAC_CHANNEL_DESCRIPTION_SIZE); + SacChannelAttributes.DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE] = ANSI_NULL; + + /* Set all the right flags */ + SacChannelAttributes.Flag = SAC_CHANNEL_FLAG_APPLICATION | SAC_CHANNEL_FLAG_INTERNAL; + SacChannelAttributes.CloseEvent = NULL; + SacChannelAttributes.HasNewDataEvent = NULL; + SacChannelAttributes.LockEvent = NULL; + SacChannelAttributes.RedrawEvent = NULL; + SacChannelAttributes.ChannelId = PRIMARY_SAC_CHANNEL_APPLICATION_GUID; + + /* Now create it */ + Status = ChanMgrCreateChannel(&SacChannel, &SacChannelAttributes); + if (NT_SUCCESS(Status)) + { + /* Try to get it back */ + Status = ChanMgrGetByHandle(SacChannel->ChannelId, &FoundChannel); + if (NT_SUCCESS(Status)) + { + /* Set it as the current and SAC channel */ + SacChannel = CurrentChannel = FoundChannel; + + /* Diasable writes for now and clear the display */ + _InterlockedExchange(&FoundChannel->WriteEnabled, FALSE); + Status = HeadlessDispatch(HeadlessCmdClearDisplay, NULL, 0, NULL, NULL); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC ConMgrInitialize: Failed dispatch\n"); + } + + /* Display the initial prompt */ + SacPutSimpleMessage(SAC_NEWLINE); + SacPutSimpleMessage(SAC_INIT_STATUS); + SacPutSimpleMessage(SAC_NEWLINE); + SacPutSimpleMessage(SAC_PROMPT); + + /* Display the current channel */ + ConMgrDisplayCurrentChannel(); + } + } + + /* Release the channel lock */ + SacReleaseMutexLock(); + return STATUS_SUCCESS; } VOID -ConMgrWorkerProcessEvents( - IN PSAC_CHANNEL Channel - ) +NTAPI +ConMgrEventMessage(IN PWCHAR EventMessage, + IN BOOLEAN LockHeld) { + /* Acquire the current channel lock if needed */ + if (!LockHeld) SacAcquireMutexLock(); + /* Send out the event message */ + SacPutSimpleMessage(2); + SacPutString(EventMessage); + SacPutSimpleMessage(3); + + /* Release the current channel lock if needed */ + if (!LockHeld) SacReleaseMutexLock(); } + +BOOLEAN +NTAPI +ConMgrSimpleEventMessage(IN ULONG MessageIndex, + IN BOOLEAN LockHeld) +{ + PWCHAR MessageBuffer; + BOOLEAN Result; + + /* Get the message to send out */ + MessageBuffer = GetMessage(MessageIndex); + if (MessageBuffer) + { + /* Send it */ + ConMgrEventMessage(MessageBuffer, LockHeld); + Result = TRUE; + } + else + { + /* It doesn't exist, fail */ + Result = FALSE; + } + + /* Return if the message was sent or not */ + return Result; +} + +NTSTATUS +NTAPI +ConMgrDisplayFastChannelSwitchingInterface(IN PSAC_CHANNEL Channel) +{ + /* FIXME: TODO */ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +ConMgrSetCurrentChannel(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status; + BOOLEAN HasRedrawEvent; + + /* Make sure the lock is held */ + SacAssertMutexLockHeld(); + + /* Check if we have a redraw event */ + Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedrawEvent); + if (!NT_SUCCESS(Status)) return Status; + + /* Clear it */ + if (HasRedrawEvent) ChannelClearRedrawEvent(CurrentChannel); + + /* Disable writes on the current channel */ + _InterlockedExchange(&CurrentChannel->WriteEnabled, 0); + + /* Release the current channel */ + Status = ChanMgrReleaseChannel(CurrentChannel); + if (!NT_SUCCESS(Status)) return Status; + + /* Set the new channel and also disable writes on it */ + CurrentChannel = Channel; + _InterlockedExchange(&Channel->WriteEnabled, 0); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ConMgrResetCurrentChannel(IN BOOLEAN KeepChannel) +{ + NTSTATUS Status; + PSAC_CHANNEL Channel; + + /* Make sure the lock is held */ + SacAssertMutexLockHeld(); + + /* Get the current SAC channel */ + Status = ChanMgrGetByHandle(SacChannel->ChannelId, &Channel); + if (NT_SUCCESS(Status)) + { + /* Set this as the current SAC channel*/ + SacChannel = Channel; + Status = ConMgrSetCurrentChannel(Channel); + if (NT_SUCCESS(Status)) + { + /* Check if the caller wants to switch or not */ + if (KeepChannel) + { + /* Nope, keep the same channel */ + Status = ConMgrDisplayCurrentChannel(); + } + else + { + /* Yep, show the switching interface */ + Status = ConMgrDisplayFastChannelSwitchingInterface(CurrentChannel); + } + } + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ConMgrChannelClose(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status = STATUS_SUCCESS; + + /* Check if we're in the right channel */ + if (ConMgrIsWriteEnabled(Channel)) + { + /* Yep, reset it */ + Status = ConMgrResetCurrentChannel(FALSE); + ASSERT(NT_SUCCESS(Status)); + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ConMgrShutdown(VOID) +{ + NTSTATUS Status; + + /* Check if we have a SAC channel */ + if (SacChannel) + { + /* Close it */ + Status = ChannelClose(SacChannel); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC ConMgrShutdown: failed closing SAC channel.\n"); + } + + /* No longer have one */ + SacChannel = NULL; + } + + /* Check if we have a current channel */ + if (CurrentChannel) + { + /* Release it */ + Status = ChanMgrReleaseChannel(CurrentChannel); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC ConMgrShutdown: failed releasing current channel\n"); + } + + /* No longer have one */ + CurrentChannel = NULL; + } + + /* All done */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ConMgrAdvanceCurrentChannel(VOID) +{ + NTSTATUS Status; + ULONG Index; + PSAC_CHANNEL Channel; + + /* Should always be called with the lock held */ + SacAssertMutexLockHeld(); + + /* Get the next active channel */ + Status = ChanMgrGetNextActiveChannel(CurrentChannel, &Index, &Channel); + if (NT_SUCCESS(Status)) + { + /* Set it as the new channel */ + Status = ConMgrSetCurrentChannel(Channel); + if (NT_SUCCESS(Status)) + { + /* Let the user switch to it */ + Status = ConMgrDisplayFastChannelSwitchingInterface(Channel); + } + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ConMgrChannelOWrite(IN PSAC_CHANNEL Channel, + IN PVOID WriteBuffer) +{ + NTSTATUS Status; + + /* Do the write with the lock held */ + SacAcquireMutexLock(); + Status = STATUS_NOT_IMPLEMENTED;// ChannelOWrite(Channel, WriteBuffer + 24, *(WriteBuffer + 20)); + SacReleaseMutexLock(); + + /* Return back to the caller */ + ASSERT(NT_SUCCESS(Status) || Status == STATUS_NOT_FOUND); + return Status; +} + +NTSTATUS +NTAPI +ConMgrGetChannelCloseMessage(IN PSAC_CHANNEL Channel, + IN NTSTATUS CloseStatus, + OUT PWCHAR OutputBuffer) +{ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +VOID +NTAPI +ConMgrProcessInputLine(VOID) +{ + ASSERT(FALSE); +} + +NTSTATUS +NTAPI +ConMgrHandleEvent(IN ULONG EventCode, + IN PSAC_CHANNEL Channel, + OUT PVOID Data) +{ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + diff --git a/reactos/drivers/sac/driver/data.c b/reactos/drivers/sac/driver/data.c index 42ebd90662d..eee9ce0c7a7 100644 --- a/reactos/drivers/sac/driver/data.c +++ b/reactos/drivers/sac/driver/data.c @@ -1,58 +1,502 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/data.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/data.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -ULONG SACDebug; +ULONG SACDebug = 0xFFFFFFFF; +BOOLEAN CommandConsoleLaunchingEnabled; +BOOLEAN GlobalDataInitialized; +KMUTEX SACCMDEventInfoMutex; +BOOLEAN IoctlSubmitted; +ULONG ProcessingType; +PKEVENT SACEvent; +HANDLE SACEventHandle; -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ VOID -FreeGlobalData( - VOID - ) +NTAPI +WorkerProcessEvents(IN PSAC_DEVICE_EXTENSION DeviceExtension) { - + /* Call the worker function */ + return ConMgrWorkerProcessEvents(DeviceExtension); } VOID -FreeDeviceData( - IN PDEVICE_OBJECT DeviceObject - ) +NTAPI +WorkerThreadStartUp(IN PVOID Context) { - + /* Call the worker function */ + WorkerProcessEvents((PSAC_DEVICE_EXTENSION)Context); } NTSTATUS -WorkerThreadStartUp( - IN PVOID Context - ) +NTAPI +BuildDeviceAcl(OUT PACL* Dacl) { - return STATUS_NOT_IMPLEMENTED; + /* TODO */ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +CreateDeviceSecurityDescriptor(IN PDEVICE_OBJECT *DeviceObject) +{ + NTSTATUS Status; + PSECURITY_DESCRIPTOR SecurityDescriptor; + BOOLEAN MemoryAllocated = FALSE; + PACL Dacl = NULL; + PVOID ObjectSecurityDescriptor = NULL; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Entering.\n"); + + /* Get the current SD of the device object */ + Status = ObGetObjectSecurity(*DeviceObject, &SecurityDescriptor, &MemoryAllocated); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC: Unable to get security descriptor, error: %x\n", Status); + NT_ASSERT(MemoryAllocated == FALSE); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Exiting with status 0x%x\n", Status); + return Status; + } + + /* Build a DACL for it */ + Status = BuildDeviceAcl(&Dacl); + if (Status >= 0) + { + ASSERT(FALSE); + } + else + { + SAC_DBG(SAC_DBG_INIT, "SAC CreateDeviceSecurityDescriptor : Unable to create Raw ACL, error : %x\n", Status); + goto CleanupPath; + } + +CleanupPath: + /* Release the SD we queried */ + ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated); + + /* Free anything else we may have allocated */ + if (ObjectSecurityDescriptor) ExFreePool(ObjectSecurityDescriptor); + if (Dacl) SacFreePool(Dacl); + + /* All done */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Exiting with status 0x%x\n", Status); + return Status; +} + +VOID +NTAPI +FreeGlobalData(VOID) +{ + UNICODE_STRING SymbolicLink; + SAC_DBG(1, "SAC FreeGlobalData: Entering.\n"); + + /* Only free if we allocated */ + if (GlobalDataInitialized) + { + /* Close the SAC event if we had created one */ + if (SACEvent) + { + ZwClose(SACEventHandle); + SACEvent = NULL; + } + + /* Destroy the cached messages */ + TearDownGlobalMessageTable(); + + /* Delete the Win32 symbolic link */ + RtlInitUnicodeString(&SymbolicLink, L"\\DosDevices\\SAC"); + IoDeleteSymbolicLink(&SymbolicLink); + + /* Tear down connections */ + ConMgrShutdown(); + + /* Tear down channels */ + ChanMgrShutdown(); + + /* Free the serial port buffer */ + if (SerialPortBuffer) SacFreePool(SerialPortBuffer); + + /* Free cached machine information */ + FreeMachineInformation(); + + /* Cleanup the custom heap allocator */ + FreeMemoryManagement(); + + /* We're back to a virgin state */ + GlobalDataInitialized = FALSE; + } + + /* All done */ + SAC_DBG(1, "SAC FreeGlobalData: Exiting.\n"); +} + +VOID +NTAPI +FreeDeviceData(IN PDEVICE_OBJECT DeviceObject) +{ + PSAC_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + KIRQL OldIrql; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Entering.\n"); + + /* Get the device extension and see how far we had gotten */ + DeviceExtension = (PSAC_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + if ((GlobalDataInitialized) && (DeviceExtension->Initialized)) + { + /* Attempt to rundown while holding the lock */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + while (DeviceExtension->RundownInProgress) + { + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Waiting....\n"); + + /* Initiate and wait for rundown */ + KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0); + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent, + Executive, + KernelMode, + FALSE, + NULL); + ASSERT(Status == STATUS_SUCCESS); + + /* Re-acquire the lock and check if rundown is done */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + } + } + + /* Now set the rundown flag while we cancel the timer */ + DeviceExtension->RundownInProgress = TRUE; + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + + /* Cancel it */ + KeCancelTimer(&DeviceExtension->Timer); + + /* Reacquire the lock*/ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + DeviceExtension->RundownInProgress = FALSE; + + /* Now do the last rundown attempt, we should be the only ones here */ + KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0); + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + KeSetEvent(&DeviceExtension->Event, DeviceExtension->PriorityBoost, 0); + Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent, + Executive, + KernelMode, + FALSE, + NULL); + ASSERT(Status == STATUS_SUCCESS); + + /* We no longer care about shutdown */ + IoUnregisterShutdownNotification(DeviceObject); + + /* We are now fully uninitialized */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + DeviceExtension->Initialized = FALSE; + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Exiting.\n"); } BOOLEAN -InitializeDeviceData( - IN PDEVICE_OBJECT DeviceObject - ) +NTAPI +InitializeDeviceData(IN PDEVICE_OBJECT DeviceObject) { - return FALSE; + PSAC_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + BOOLEAN EnableData; + ULONG PriorityValue; + NTSTATUS Status; + LARGE_INTEGER DueTime; + PWCHAR Message; + PAGED_CODE(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); + + /* If we already did this, bail out */ + if (DeviceExtension->Initialized) goto SuccessExit; + + /* Setup the DO flags */ + DeviceObject->Flags |= DO_DIRECT_IO; + DeviceObject->StackSize = 16; + + /* Setup the device extension */ + DeviceExtension->DeviceObject = DeviceObject; + DeviceExtension->PriorityBoost = IO_SERIAL_INCREMENT; + DeviceExtension->PriorityFail = 0; + DeviceExtension->RundownInProgress = 0; + + /* Initialize locks, events, timers, DPCs, etc... */ + KeInitializeTimer(&DeviceExtension->Timer); + KeInitializeDpc(&DeviceExtension->Dpc, TimerDpcRoutine, DeviceExtension); + KeInitializeSpinLock(&DeviceExtension->Lock); + KeInitializeEvent(&DeviceExtension->Event, SynchronizationEvent, 0); + InitializeListHead(&DeviceExtension->List); + + /* Attempt to enable HDL support */ + EnableData = TRUE; + Status = HeadlessDispatch(HeadlessCmdEnableTerminal, + &EnableData, + sizeof(EnableData), + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + /* Bail out if we couldn't even get this far */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (1) with status FALSE\n"); + return FALSE; + } + + /* Remember which process we started in */ + DeviceExtension->Process = IoGetCurrentProcess(); + + /* Protect the device against non-admins */ + Status = CreateDeviceSecurityDescriptor(&DeviceExtension->DeviceObject); + if (!NT_SUCCESS(Status)) + { + /* Write down why we failed */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (2) with status FALSE\n"); + + /* Disable the HDL terminal on failure */ + EnableData = FALSE; + Status = HeadlessDispatch(HeadlessCmdEnableTerminal, + &EnableData, + sizeof(EnableData), + NULL, + NULL); + if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n"); + + /* Bail out */ + return FALSE; + } + + /* Create the worker thread */ + Status = PsCreateSystemThread(&DeviceExtension->WorkerThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + NULL, + WorkerThreadStartUp, + DeviceExtension); + if (!NT_SUCCESS(Status)) + { + /* Write down why we failed */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (3) with status FALSE\n"); + + /* Disable the HDL terminal on failure */ + EnableData = FALSE; + Status = HeadlessDispatch(HeadlessCmdEnableTerminal, + &EnableData, + sizeof(EnableData), + NULL, + NULL); + if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n"); + + /* Bail out */ + return FALSE; + } + + /* Set the priority of our thread to highest */ + PriorityValue = HIGH_PRIORITY; + Status = NtSetInformationThread(DeviceExtension->WorkerThreadHandle, + ThreadPriority, + &PriorityValue, + sizeof(PriorityValue)); + if (!NT_SUCCESS(Status)) + { + /* For debugging, write down why we failed */ + SAC_DBG(1, "Exiting (6) with status FALSE\n"); + DeviceExtension->PriorityFail = TRUE; + + /* Initialize rundown and wait for the thread to do it */ + KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0); + KeSetEvent(&DeviceExtension->Event, DeviceExtension->PriorityBoost, 0); + Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent, + Executive, + KernelMode, + FALSE, + NULL); + ASSERT(Status == STATUS_SUCCESS); + + /* Disable the HDL terminal on failure */ + EnableData = FALSE; + Status = HeadlessDispatch(HeadlessCmdEnableTerminal, + &EnableData, + sizeof(EnableData), + NULL, + 0); + if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n"); + + /* Bail out */ + return FALSE; + } + + /* The first "packet" is the machine information in XML... */ + Status = TranslateMachineInformationXML(&Message, NULL); + if (NT_SUCCESS(Status)) + { + /* Go ahead and send it */ + UTF8EncodeAndSend(L"\r\n"); + UTF8EncodeAndSend(Message); + + /* Free the temporary buffer */ + SacFreePool(Message); + } + + /* Finally, initialize the I/O Manager */ + Status = ConMgrInitialize(); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Set the timer. Once this is done, the device is initialized */ + DueTime.QuadPart = -4000; + KeSetTimerEx(&DeviceExtension->Timer, DueTime, 4, &DeviceExtension->Dpc); + DeviceExtension->Initialized = TRUE; + +SuccessExit: + /* Success path -- everything worked */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n"); + return TRUE; } BOOLEAN -InitializeGlobalData( - IN PUNICODE_STRING RegistryPath, - IN PDRIVER_OBJECT DriverObject - ) +NTAPI +InitializeGlobalData(IN PUNICODE_STRING RegistryPath, + IN PDRIVER_OBJECT DriverObject) { - return FALSE; + NTSTATUS Status; + UNICODE_STRING LinkName; + UNICODE_STRING DeviceName; + UNICODE_STRING EventName; + PAGED_CODE(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); + + /* If we already did this, bail out */ + if (!GlobalDataInitialized) goto SuccessExit; + + /* Setup the symbolic link for Win32 support */ + RtlInitUnicodeString(&LinkName, L"\\DosDevices\\SAC"); + RtlInitUnicodeString(&DeviceName, L"\\Device\\SAC"); + Status = IoCreateSymbolicLink(&LinkName, &DeviceName); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Initialize the internal heap manager */ + if (!InitializeMemoryManagement()) + { + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status FALSE\n"); + return FALSE; + } + + /* Preload the messages in memory */ + Status = PreloadGlobalMessageTable(DriverObject->DriverStart); + if (!NT_SUCCESS(Status)) + { + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "unable to pre-load message table: %X\n", Status); + return FALSE; + } + + /* Check if the administrator enabled this */ + Status = GetCommandConsoleLaunchingPermission(&CommandConsoleLaunchingEnabled); + if (!NT_SUCCESS(Status)) + { + /* Is it enabled? */ + if (CommandConsoleLaunchingEnabled) + { + /* Set the service start type to the correct value */ + Status = ImposeSacCmdServiceStartTypePolicy(); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "failed ImposeSacCmdServiceStartTypePolicy: %X\n", Status); + } + } + + /* We're going to keep going with the default */ + SAC_DBG(SAC_DBG_INIT, "failed GetCommandConsoleLaunchingPermission: %X\n", Status); + } + + /* Allocate the UTF-8 Conversion Buffer */ + Utf8ConversionBuffer = SacAllocatePool(Utf8ConversionBufferSize, GLOBAL_BLOCK_TAG); + if (!Utf8ConversionBuffer) + { + /* Handle failure case */ + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "unable to allocate memory for UTF8 translation\n"); + return FALSE; + } + + /* Initialize the channel manager */ + Status = ChanMgrInitialize(); + if (!NT_SUCCESS(Status)) + { + /* Handle failure case */ + SacFreePool(Utf8ConversionBuffer); + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "Failed to create SAC Channel\n"); + return FALSE; + } + + /* Allocate the serial port buffer */ + SerialPortBuffer = SacAllocatePool(SAC_SERIAL_PORT_BUFFER_SIZE, GLOBAL_BLOCK_TAG); + if (!SerialPortBuffer) + { + /* Handle failure case */ + SacFreePool(Utf8ConversionBuffer); + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "Failed to allocate Serial Port Buffer\n"); + return FALSE; + } + + /* Zero it out */ + RtlZeroMemory(SerialPortBuffer, SAC_SERIAL_PORT_BUFFER_SIZE); + + /* Initialize command events. After this, driver data is good to go */ + KeInitializeMutex(&SACCMDEventInfoMutex, FALSE); + InitializeCmdEventInfo(); + GlobalDataInitialized = TRUE; + ProcessingType = 0; + IoctlSubmitted = 0; + + /* Create the SAC event */ + RtlInitUnicodeString(&EventName, L"\\SACEvent"); + SACEvent = IoCreateSynchronizationEvent(&EventName, &SACEventHandle); + if (!SACEvent) + { + /* Handle failure case */ + SacFreePool(Utf8ConversionBuffer); + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with event NULL\n"); + return FALSE; + } + + /* Cache machine information */ + InitializeMachineInformation(); + + /* Register it */ + Status = RegisterBlueScreenMachineInformation(); + if (!NT_SUCCESS(Status)) + { + /* Handle failure case */ + SacFreePool(Utf8ConversionBuffer); + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "Failed to register blue screen machine info\n"); + return FALSE; + } + +SuccessExit: + /* Success path -- everything worked */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n"); + return TRUE; } + diff --git a/reactos/drivers/sac/driver/dispatch.c b/reactos/drivers/sac/driver/dispatch.c index 58ffaca4115..1af10f57d50 100644 --- a/reactos/drivers/sac/driver/dispatch.c +++ b/reactos/drivers/sac/driver/dispatch.c @@ -1,88 +1,90 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/dispatch.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/dispatch.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ NTSTATUS NTAPI -DispatchDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) +DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -DispatchShutdownControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) +NTAPI +DispatchShutdownControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -DispatchCreate( - IN PSAC_DEVICE_EXTENSION DeviceExtension, - IN PIRP Irp - ) +NTAPI +DispatchCreate(IN PSAC_DEVICE_EXTENSION DeviceExtension, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -DispatchClose( - IN PSAC_DEVICE_EXTENSION DeviceExtension, - IN PIRP Irp - ) +NTAPI +DispatchClose(IN PSAC_DEVICE_EXTENSION DeviceExtension, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -Dispatch( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) +NTAPI +Dispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -WorkerProcessEvents( - IN PSAC_CHANNEL Channel - ) -{ - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } VOID -TimerDpcRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2 - ) +NTAPI +TimerDpcRoutine(IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) { } VOID -UnloadHandler( - IN PDRIVER_OBJECT DriverObject - ) +NTAPI +UnloadHandler(IN PDRIVER_OBJECT DriverObject) { + PDEVICE_OBJECT DeviceObject, NextDevice; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC UnloadHandler: Entering.\n"); + /* Go overy ever device part of the driver */ + DeviceObject = DriverObject->DeviceObject; + while (DeviceObject) + { + /* Free and delete the information about this device */ + NextDevice = DeviceObject->NextDevice; + FreeDeviceData(DeviceObject); + IoDeleteDevice(DeviceObject); + + /* Move on to the next one */ + DeviceObject = NextDevice; + } + + /* Free the driver data and exit */ + FreeGlobalData(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC UnloadHandler: Exiting.\n"); } diff --git a/reactos/drivers/sac/driver/init.c b/reactos/drivers/sac/driver/init.c index 0542d1091da..e0f0a4588a5 100644 --- a/reactos/drivers/sac/driver/init.c +++ b/reactos/drivers/sac/driver/init.c @@ -1,94 +1,94 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/init.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/init.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ NTSTATUS NTAPI -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) { - HEADLESS_RSP_QUERY_INFO HeadlessInformation; - ULONG InfoSize; - NTSTATUS Status; - UNICODE_STRING DriverName; - PDEVICE_OBJECT DeviceObject; - PSAC_DEVICE_EXTENSION DeviceExtension; - PAGED_CODE(); + HEADLESS_RSP_QUERY_INFO HeadlessInformation; + ULONG InfoSize = sizeof(HeadlessInformation); + NTSTATUS Status; + UNICODE_STRING DriverName; + PDEVICE_OBJECT DeviceObject; + PSAC_DEVICE_EXTENSION DeviceExtension; + PAGED_CODE(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); + /* Check if EMS is enabled in the kernel */ + HeadlessDispatch(HeadlessCmdQueryInformation, + NULL, + 0, + &HeadlessInformation, + &InfoSize); + if ((HeadlessInformation.Serial.TerminalType != HeadlessUndefinedPortType) && + ((HeadlessInformation.Serial.TerminalType != HeadlessSerialPort) || + (HeadlessInformation.Serial.TerminalAttached))) + { + /* It is, so create the device */ + RtlInitUnicodeString(&DriverName, L"\\Device\\SAC"); + Status = IoCreateDevice(DriverObject, + sizeof(SAC_DEVICE_EXTENSION), + &DriverName, + FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &DeviceObject); + if (NT_SUCCESS(Status)) + { + /* Setup the device extension */ + DeviceExtension = DeviceObject->DeviceExtension; + DeviceExtension->Initialized = FALSE; - HeadlessDispatch( - HeadlessCmdQueryInformation, - NULL, - 0, - &HeadlessInformation, - &InfoSize - ); - if ((HeadlessInformation.Serial.TerminalType != HeadlessUndefinedPortType) && - ((HeadlessInformation.Serial.TerminalType != HeadlessSerialPort) || - (HeadlessInformation.Serial.TerminalAttached))) - { - RtlInitUnicodeString(&DriverName, L"\\Device\\SAC"); + /* Initialize the driver object */ + RtlFillMemoryUlong(DriverObject->MajorFunction, + RTL_NUMBER_OF(DriverObject->MajorFunction), + (ULONG_PTR)Dispatch); + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; + DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DispatchShutdownControl; + DriverObject->FastIoDispatch = NULL; + DriverObject->DriverUnload = UnloadHandler; - Status = IoCreateDevice( - DriverObject, - sizeof(SAC_DEVICE_EXTENSION), - &DriverName, - FILE_DEVICE_UNKNOWN, - FILE_DEVICE_SECURE_OPEN, - FALSE, - &DeviceObject - ); - if (NT_SUCCESS(Status)) - { - DeviceExtension = DeviceObject->DeviceExtension; - DeviceExtension->Initialized = FALSE; + /* Initialize driver data */ + if (InitializeGlobalData(RegistryPath, DriverObject)) + { + /* Initialize device data */ + if (InitializeDeviceData(DeviceObject)) + { + /* We're all good, register a shutdown notification */ + IoRegisterShutdownNotification(DeviceObject); + return Status; + } + } - RtlFillMemoryUlong( - DriverObject->MajorFunction, - sizeof(DriverObject->MajorFunction) / sizeof(PVOID), - (ULONG_PTR)Dispatch); - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = - DispatchDeviceControl; - DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = - DispatchShutdownControl; - DriverObject->FastIoDispatch = NULL; - DriverObject->DriverUnload = UnloadHandler; + /* One of the initializations failed, bail out */ + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + /* Print a debug statement if enabled */ + SAC_DBG(SAC_DBG_INIT, "unable to create device object: %X\n", Status); + } - if (InitializeGlobalData(RegistryPath, DriverObject)) - { - if (InitializeDeviceData(DeviceObject)) - { - IoRegisterShutdownNotification(DeviceObject); - return Status; - } - } + /* Free any data we may have allocated and exit with failure */ + FreeGlobalData(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status 0x%x\n", Status); + return Status; + } - Status = STATUS_INSUFFICIENT_RESOURCES; - } - else - { - SAC_DBG(SAC_DBG_INIT, "unable to create device object: %X\n", Status); - } - - FreeGlobalData(); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status 0x%x\n", Status); - return Status; - } - - return STATUS_PORT_DISCONNECTED; + /* EMS is not enabled */ + return STATUS_PORT_DISCONNECTED; } diff --git a/reactos/drivers/sac/driver/memory.c b/reactos/drivers/sac/driver/memory.c index fb77febccf6..6dfe2f1625e 100644 --- a/reactos/drivers/sac/driver/memory.c +++ b/reactos/drivers/sac/driver/memory.c @@ -1,108 +1,112 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/memory.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/memory.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ LONG TotalFrees, TotalBytesFreed, TotalAllocations, TotalBytesAllocated; KSPIN_LOCK MemoryLock; PSAC_MEMORY_LIST GlobalMemoryList; -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ BOOLEAN +NTAPI InitializeMemoryManagement(VOID) { - PSAC_MEMORY_ENTRY Entry; + PSAC_MEMORY_ENTRY Entry; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n"); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n"); + /* Allocate a nonpaged heap for us to use */ + GlobalMemoryList = ExAllocatePoolWithTagPriority(NonPagedPool, + SAC_MEMORY_LIST_SIZE, + INITIAL_BLOCK_TAG, + HighPoolPriority); + if (GlobalMemoryList) + { + /* Initialize a lock for it */ + KeInitializeSpinLock(&MemoryLock); - GlobalMemoryList = ExAllocatePoolWithTagPriority( - NonPagedPool, - SAC_MEMORY_LIST_SIZE, - INITIAL_BLOCK_TAG, - HighPoolPriority); - if (GlobalMemoryList) - { - KeInitializeSpinLock(&MemoryLock); + /* Initialize the head of the list */ + GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE; + GlobalMemoryList->LocalDescriptor = (PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1); + GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST); + GlobalMemoryList->Next = NULL; - GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE; - GlobalMemoryList->LocalDescriptor = - (PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1); - GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST); + /* Initialize the first free entry */ + Entry = GlobalMemoryList->LocalDescriptor; + Entry->Signature = LOCAL_MEMORY_SIGNATURE; + Entry->Tag = FREE_POOL_TAG; + Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY); - Entry = GlobalMemoryList->LocalDescriptor; - Entry->Signature = LOCAL_MEMORY_SIGNATURE; - Entry->Tag = FREE_POOL_TAG; - Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY); + /* All done */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n"); + return TRUE; + } - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n"); - return TRUE; - } - - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n"); - return FALSE; + /* No pool available to manage our heap */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n"); + return FALSE; } VOID -FreeMemoryManagement( - VOID - ) +NTAPI +FreeMemoryManagement(VOID) { - PSAC_MEMORY_LIST Next; - KIRQL OldIrql; + PSAC_MEMORY_LIST Next; + KIRQL OldIrql; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n"); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n"); + /* Acquire the memory lock while freeing the list(s) */ + KeAcquireSpinLock(&MemoryLock, &OldIrql); + while (GlobalMemoryList) + { + ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE); - KeAcquireSpinLock(&MemoryLock, &OldIrql); - while (GlobalMemoryList) - { - ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE); + /* While outisde of the lock, save the next list and free this one */ + KeReleaseSpinLock(&MemoryLock, OldIrql); + Next = GlobalMemoryList->Next; + ExFreePoolWithTag(GlobalMemoryList, 0); - KeReleaseSpinLock(&MemoryLock, OldIrql); + /* Reacquire the lock and see if there was another list to free */ + KeAcquireSpinLock(&MemoryLock, &OldIrql); + GlobalMemoryList = Next; + } - Next = GlobalMemoryList->Next; - - ExFreePoolWithTag(GlobalMemoryList, 0); - - KeAcquireSpinLock(&MemoryLock, &OldIrql); - GlobalMemoryList = Next; - } - - KeReleaseSpinLock(&MemoryLock, OldIrql); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n"); + /* All done */ + KeReleaseSpinLock(&MemoryLock, OldIrql); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n"); } PVOID -MyAllocatePool( - IN SIZE_T PoolSize, - IN ULONG Tag, - IN PCHAR File, - IN ULONG Line - ) +NTAPI +MyAllocatePool(IN SIZE_T PoolSize, + IN ULONG Tag, + IN PCHAR File, + IN ULONG Line) { - KIRQL OldIrql; - PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor; - PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor; - ULONG GlobalSize, ActualSize; - PVOID Buffer; + KIRQL OldIrql; + PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor; + PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor; + ULONG GlobalSize, ActualSize; + PVOID Buffer; + ASSERT("Tag != FREE_POOL_TAG"); + SAC_DBG(SAC_DBG_MM, "Entering.\n"); - ASSERT("Tag != FREE_POOL_TAG"); + /* Acquire the memory allocation lock and align the size request */ + KeAcquireSpinLock(&MemoryLock, &OldIrql);; + PoolSize = ALIGN_UP(PoolSize, ULONGLONG); - SAC_DBG(SAC_DBG_MM, "Entering.\n"); - - OldIrql = KfAcquireSpinLock(&MemoryLock); - PoolSize = ALIGN_UP(PoolSize, ULONGLONG); - - GlobalDescriptor = GlobalMemoryList; +#if _USE_SAC_HEAP_ALLOCATOR_ + GlobalDescriptor = GlobalMemoryList; KeAcquireSpinLock(&MemoryLock, &OldIrql); while (GlobalDescriptor) { @@ -189,43 +193,60 @@ MyAllocatePool( LocalDescriptor->Size = PoolSize; } } +#else + /* Shut the compiler up */ + NewDescriptor = GlobalDescriptor = NULL; + GlobalSize = (ULONG)NewDescriptor; + ActualSize = GlobalSize; + NextDescriptor = (PVOID)ActualSize; + NewDescriptor = (PVOID)NextDescriptor; - LocalDescriptor->Tag = Tag; - KeReleaseSpinLock(&MemoryLock, OldIrql); + /* Use the NT pool allocator */ + LocalDescriptor = ExAllocatePoolWithTag(NonPagedPool, + PoolSize + sizeof(*LocalDescriptor), + Tag); + LocalDescriptor->Size = PoolSize; +#endif + /* Set the tag, and release the lock */ + LocalDescriptor->Tag = Tag; + KeReleaseSpinLock(&MemoryLock, OldIrql); - InterlockedIncrement(&TotalAllocations); - InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size); - SAC_DBG(1, "Returning block 0x%X.\n", LocalDescriptor); + /* Update our performance counters */ + InterlockedIncrement(&TotalAllocations); + InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size); - Buffer = LocalDescriptor + 1; - RtlZeroMemory(Buffer, PoolSize); - return Buffer; + /* Return the buffer and zero it */ + SAC_DBG(SAC_DBG_MM, "Returning block 0x%X.\n", LocalDescriptor); + Buffer = LocalDescriptor + 1; + RtlZeroMemory(Buffer, PoolSize); + return Buffer; } VOID -MyFreePool( - IN PVOID *Block - ) +NTAPI +MyFreePool(IN PVOID *Block) { - PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor; - PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor; - ULONG GlobalSize, LocalSize; - PSAC_MEMORY_LIST GlobalDescriptor; - KIRQL OldIrql; + PSAC_MEMORY_ENTRY NextDescriptor; + PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor; + PSAC_MEMORY_ENTRY LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY)); + ULONG GlobalSize, LocalSize; + PSAC_MEMORY_LIST GlobalDescriptor; + KIRQL OldIrql; + SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor); - LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY)); + /* Make sure this was a valid entry */ + ASSERT(LocalDescriptor->Size > 0); + ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE); - SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor); + /* Update performance counters */ + InterlockedIncrement(&TotalFrees); + InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size); - ASSERT(LocalDescriptor->Size > 0); - ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE); + /* Acquire the memory alliocation lock */ + GlobalDescriptor = GlobalMemoryList; + KeAcquireSpinLock(&MemoryLock, &OldIrql); - InterlockedIncrement(&TotalFrees); - - InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size); - - GlobalDescriptor = GlobalMemoryList; - KeAcquireSpinLock(&MemoryLock, &OldIrql); +#if _USE_SAC_HEAP_ALLOCATOR_ while (GlobalDescriptor) { ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE); @@ -297,10 +318,22 @@ MyFreePool( FoundDescriptor->Size += (LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY)); } +#else + /* Shut the compiler up */ + LocalSize = GlobalSize = 0; + ThisDescriptor = (PVOID)LocalSize; + NextDescriptor = (PVOID)GlobalSize; + GlobalDescriptor = (PVOID) ThisDescriptor; + FoundDescriptor = (PVOID)GlobalDescriptor; + GlobalDescriptor = (PVOID) NextDescriptor; + NextDescriptor = (PVOID) FoundDescriptor; - KeReleaseSpinLock(&MemoryLock, OldIrql); - *Block = NULL; + /* Use the NT pool allocator*/ + ExFreePool(LocalDescriptor); +#endif - SAC_DBG(SAC_DBG_MM, "exiting.\n"); - return; + /* Release the lock, delete the address, and return */ + KeReleaseSpinLock(&MemoryLock, OldIrql); + *Block = NULL; + SAC_DBG(SAC_DBG_MM, "exiting.\n"); } diff --git a/reactos/drivers/sac/driver/rawchan.c b/reactos/drivers/sac/driver/rawchan.c index 6a38bd0a97c..098d78dd97a 100644 --- a/reactos/drivers/sac/driver/rawchan.c +++ b/reactos/drivers/sac/driver/rawchan.c @@ -1,143 +1,373 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/rawchan.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/rawchan.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ + +#define SAC_RAW_OBUFFER_SIZE 0x2000 +#define SAC_RAW_IBUFFER_SIZE 0x2000 NTSTATUS -RawChannelCreate( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelCreate(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER(Channel); + + Channel->OBuffer = SacAllocatePool(SAC_RAW_OBUFFER_SIZE, GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(Channel->OBuffer); + + Channel->IBuffer = SacAllocatePool(SAC_RAW_IBUFFER_SIZE, GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(Channel->IBuffer); + + Channel->OBufferIndex = 0; + Channel->OBufferFirstGoodIndex = 0; + Channel->ChannelHasNewIBufferData = FALSE; + Channel->ChannelHasNewOBufferData = FALSE; + + return STATUS_SUCCESS; } NTSTATUS -RawChannelDestroy( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelDestroy(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER(Channel); + + if (Channel->OBuffer) + { + SacFreePool(Channel->OBuffer); + } + + if (Channel->IBuffer) + { + SacFreePool(Channel->IBuffer); + } + + return ChannelDestroy(Channel); +} + +FORCEINLINE +BOOLEAN +ChannelHasNewOBufferData(IN PSAC_CHANNEL Channel) +{ + return Channel->ChannelHasNewOBufferData; +} + +FORCEINLINE +BOOLEAN +ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel) +{ + return Channel->ChannelHasNewIBufferData; } NTSTATUS -RawChannelORead( - IN PSAC_CHANNEL Channel, - IN PCHAR Buffer, - IN ULONG BufferSize, - OUT PULONG ByteCount - ) +NTAPI +RawChannelORead(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + OUT PULONG ByteCount) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + ULONG NextIndex; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Buffer); + CHECK_PARAMETER3(BufferSize > 0); + CHECK_PARAMETER4(ByteCount); + + *ByteCount = 0; + + if (ChannelHasNewOBufferData(Channel)) + { + Status = STATUS_SUCCESS; + + while (TRUE) + { + Buffer[(*ByteCount)++] = Channel->OBuffer[Channel->OBufferFirstGoodIndex]; + + NextIndex = (Channel->OBufferFirstGoodIndex + 1) & (SAC_OBUFFER_SIZE - 1); + Channel->OBufferFirstGoodIndex = NextIndex; + + if (NextIndex == Channel->OBufferIndex) + { + _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0); + break; + } + + ASSERT(*ByteCount > 0); + + if (*ByteCount >= BufferSize) break; + } + } + else + { + Status = STATUS_NO_DATA_DETECTED; + } + + if (Channel->OBufferFirstGoodIndex == Channel->OBufferIndex) + { + ASSERT(ChannelHasNewOBufferData(Channel) == FALSE); + } + + if (ChannelHasNewOBufferData(Channel) == FALSE) + { + ASSERT(Channel->OBufferFirstGoodIndex == Channel->OBufferIndex); + } + + return Status; } NTSTATUS -RawChannelOEcho( - IN PSAC_CHANNEL Channel, - IN PWCHAR String, - IN ULONG Length - ) +NTAPI +RawChannelOEcho(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status = STATUS_SUCCESS; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(String); + + if (Length) + { + Status = ConMgrWriteData(Channel, String, Length); + if (NT_SUCCESS(Status)) ConMgrFlushData(Channel); + } + + return Status; } NTSTATUS -RawChannelOWrite2( - IN PSAC_CHANNEL Channel, - IN PCHAR String, - IN ULONG Size - ) +NTAPI +RawChannelOWrite2(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Size) { - return STATUS_NOT_IMPLEMENTED; + BOOLEAN Overflow; + ULONG i, NextIndex; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(String); + + Overflow = FALSE; + + for (i = 0; i < Size; i++) + { + if ((Channel->OBufferIndex == Channel->OBufferFirstGoodIndex) && + ((i) || (ChannelHasNewOBufferData(Channel)))) + { + Overflow = TRUE; + } + + ASSERT(Channel->OBufferIndex < SAC_RAW_OBUFFER_SIZE); + + Channel->OBuffer[Channel->OBufferIndex] = String[i]; + + NextIndex = (Channel->OBufferIndex + 1) & (SAC_RAW_OBUFFER_SIZE - 1); + Channel->OBufferIndex = NextIndex; + + if (Overflow) Channel->OBufferFirstGoodIndex = NextIndex; + } + + _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 1); + + return STATUS_SUCCESS; } NTSTATUS -RawChannelOFlush( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelOFlush(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + ULONG ByteCount; + CHAR Dummy; + CHECK_PARAMETER1(Channel); + + while (ChannelHasNewOBufferData(Channel)) + { + Status = RawChannelORead(Channel, &Dummy, sizeof(Dummy), &ByteCount); + if (!NT_SUCCESS(Status)) return Status; + + CHECK_PARAMETER_WITH_STATUS(ByteCount == 1, STATUS_UNSUCCESSFUL); + + Status = ConMgrWriteData(Channel, &Dummy, sizeof(Dummy)); + if (!NT_SUCCESS(Status)) return Status; + } + + return ConMgrFlushData(Channel); } ULONG -RawChannelGetIBufferIndex( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelGetIBufferIndex(IN PSAC_CHANNEL Channel) { - return 0; + ASSERT(Channel); + ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE); + + return Channel->IBufferIndex; } VOID -RawChannelSetIBufferIndex( - IN PSAC_CHANNEL Channel, - IN ULONG BufferIndex - ) +NTAPI +RawChannelSetIBufferIndex(IN PSAC_CHANNEL Channel, + IN ULONG BufferIndex) { + NTSTATUS Status; + ASSERT(Channel); + ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE); + Channel->IBufferIndex = BufferIndex; + Channel->ChannelHasNewIBufferData = BufferIndex != 0; + + if (!Channel->IBufferIndex) + { + if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) + { + ChannelClearEvent(Channel, HasNewDataEvent); + UNREFERENCED_PARAMETER(Status); + } + } } NTSTATUS -RawChannelOWrite( - IN PSAC_CHANNEL Channel, - IN PWCHAR String, - IN ULONG Length - ) +NTAPI +RawChannelOWrite(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(String); + + if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled)) + { + return RawChannelOEcho(Channel, String, Length); + } + + return RawChannelOWrite2(Channel, String, Length); } NTSTATUS -RawChannelIRead( - IN PSAC_CHANNEL Channel, - IN PCHAR Buffer, - IN ULONG BufferSize, - IN PULONG ReturnBufferSize - ) +NTAPI +RawChannelIRead(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN PULONG ReturnBufferSize) { - return STATUS_NOT_IMPLEMENTED; + ULONG CopyChars; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Buffer); + CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); + + *ReturnBufferSize = 0; + + if (Channel->ChannelInputBufferLength(Channel) == 0) + { + ASSERT(ChannelHasNewIBufferData(Channel) == FALSE); + } + else + { + CopyChars = Channel->ChannelInputBufferLength(Channel); + if (CopyChars > BufferSize) CopyChars = BufferSize; + ASSERT(CopyChars <= Channel->ChannelInputBufferLength(Channel)); + + RtlCopyMemory(Buffer, Channel->IBuffer, CopyChars); + + RawChannelSetIBufferIndex(Channel, + RawChannelGetIBufferIndex(Channel) - CopyChars); + + if (Channel->ChannelInputBufferLength(Channel)) + { + RtlMoveMemory(Channel->IBuffer, + &Channel->IBuffer[CopyChars], + Channel->ChannelInputBufferLength(Channel)); + } + + *ReturnBufferSize = CopyChars; + } + + return STATUS_SUCCESS; } NTSTATUS -RawChannelIBufferIsFull( - IN PSAC_CHANNEL Channel, - PBOOLEAN BufferStatus - ) +NTAPI +RawChannelIBufferIsFull(IN PSAC_CHANNEL Channel, + OUT PBOOLEAN BufferStatus) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(BufferStatus); + + *BufferStatus = RawChannelGetIBufferIndex(Channel) > SAC_RAW_IBUFFER_SIZE; + return STATUS_SUCCESS; } ULONG -RawChannelIBufferLength( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelIBufferLength(IN PSAC_CHANNEL Channel) { - return 0; + ASSERT(Channel); + return RawChannelGetIBufferIndex(Channel); } CHAR -RawChannelIReadLast( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelIReadLast(IN PSAC_CHANNEL Channel) { - return 0; + UCHAR LastChar = 0; + + ASSERT(Channel); + + if (Channel->ChannelInputBufferLength(Channel)) + { + RawChannelSetIBufferIndex(Channel, RawChannelGetIBufferIndex(Channel) - 1); + + LastChar = Channel->IBuffer[RawChannelGetIBufferIndex(Channel)]; + Channel->IBuffer[RawChannelGetIBufferIndex(Channel)] = 0; + } + + return LastChar; } NTSTATUS -RawChannelIWrite( - IN PSAC_CHANNEL Channel, - IN PCHAR Buffer, - IN ULONG BufferSize - ) +NTAPI +RawChannelIWrite(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + BOOLEAN IsFull; + ULONG Index; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Buffer); + CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); + + Status = RawChannelIBufferIsFull(Channel, &IsFull); + if (!NT_SUCCESS(Status)) return Status; + + if (IsFull) return STATUS_UNSUCCESSFUL; + + Index = RawChannelGetIBufferIndex(Channel); + if ((SAC_RAW_IBUFFER_SIZE - Index) >= BufferSize) return STATUS_INSUFFICIENT_RESOURCES; + + RtlCopyMemory(&Channel->IBuffer[Index], Buffer, BufferSize); + + RawChannelSetIBufferIndex(Channel, BufferSize + Index); + + if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) + { + ChannelSetEvent(Channel, HasNewDataEvent); + } + + return STATUS_SUCCESS; } diff --git a/reactos/drivers/sac/driver/sacdrv.h b/reactos/drivers/sac/driver/sacdrv.h index 0936712eb61..fef618c989a 100644 --- a/reactos/drivers/sac/driver/sacdrv.h +++ b/reactos/drivers/sac/driver/sacdrv.h @@ -1,390 +1,1016 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/sacdrv.h - * PURPOSE: Header for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/sacdrv.h + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ + #include -#include +#include +#include +#include +#include +#include +#include <../../../ntoskrnl/include/internal/hdl.h> +#include +#include -#define SAC_DBG_ENTRY_EXIT 0x01 -#define SAC_DBG_INIT 0x04 -#define SAC_DBG_MM 0x1000 +/* DEFINES *******************************************************************/ -#define SAC_DBG(x, ...) \ - if (SACDebug & x) \ - { \ - DbgPrint("SAC %s: ", __FUNCTION__); \ - DbgPrint(__VA_ARGS__); \ - } +// +// SAC Heap Allocator Macros +// +#define SacAllocatePool(Length, Tag) \ + MyAllocatePool(Length, Tag, __FILE__, __LINE__) +#define SacFreePool(Pointer) \ + MyFreePool((PVOID*)(&Pointer)) -#define CHECK_PARAMETER_WITH_STATUS(Parameter, Status) \ -{ \ - ASSERT((Parameter)); \ - if (!Parameter) \ - { \ - return Status; \ - } \ +// +// SAC Debugging Macro and Constants +// +#define SAC_DBG_ENTRY_EXIT 0x01 +#define SAC_DBG_UTIL 0x02 +#define SAC_DBG_INIT 0x04 +#define SAC_DBG_MM 0x1000 +#define SAC_DBG(x, ...) \ + if (SACDebug & x) \ + { \ + DbgPrint("SAC %s: ", __FUNCTION__); \ + DbgPrint(__VA_ARGS__); \ + } + +// +// SAC Parameter Checking Macros +// +#define CHECK_PARAMETER_WITH_STATUS(Parameter, Status) \ +{ \ + ASSERT(((PVOID)(Parameter)) != NULL); \ + if (((PVOID)(Parameter)) == NULL) \ + { \ + return Status; \ + } \ } -#define CHECK_PARAMETER(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER) -#define CHECK_PARAMETER1(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_1) -#define CHECK_PARAMETER2(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_2) -#define CHECK_PARAMETER3(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_3) -#define CHECK_ALLOCATION(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_OUT_OF_MEMORY) - -#define SacAllocatePool(Length, Tag) \ - MyAllocatePool(Length, Tag, __FILE__, __LINE__) +#define CHECK_PARAMETER(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER) +#define CHECK_PARAMETER1(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_1) +#define CHECK_PARAMETER2(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_2) +#define CHECK_PARAMETER3(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_3) +#define CHECK_PARAMETER4(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_4) +#define CHECK_ALLOCATION(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_NO_MEMORY) -#define ChannelLock(Channel, x) \ -{ \ - KeWaitForSingleObject( \ - &(Channel)->x.Lock, \ - Executive, \ - KernelMode, \ - FALSE, \ - NULL); \ - ASSERT((Channel)->x.RefCount == 0); \ - InterlockedIncrement(&(Channel)->x.RefCount); \ +// +// SAC Channel Event Macros +// +#define ChannelInitializeEvent(Channel, Attributes, x) \ +{ \ + PVOID Object, WaitObject; \ + if (Attributes->x) \ + { \ + if (!VerifyEventWaitable(Attributes->x, &Object, &WaitObject)) \ + { \ + goto FailChannel; \ + } \ + Channel->x = Attributes->x; \ + Channel->x##ObjectBody = Object; \ + Channel->x##WaitObjectBody = WaitObject; \ + } \ +} +#define ChannelUninitializeEvent(Channel, x, f) \ +{ \ + ASSERT(ChannelGetFlags(Channel) & (f)); \ + ASSERT(Channel->x##ObjectBody); \ + ASSERT(Channel->x##WaitObjectBody); \ + if (Channel->x##ObjectBody) \ + { \ + ObDereferenceObject(Channel->x##ObjectBody); \ + Channel->Flags &= ~(f); \ + Channel->x = NULL; \ + Channel->x##ObjectBody = NULL; \ + Channel->x##WaitObjectBody = NULL; \ + } \ +} +#define ChannelSetEvent(Channel, x) \ +{ \ + ASSERT(Channel->x); \ + ASSERT(Channel->x##ObjectBody); \ + ASSERT(Channel->x##WaitObjectBody); \ + if (Channel->x##WaitObjectBody) \ + { \ + KeSetEvent(Channel->x##WaitObjectBody, EVENT_INCREMENT, FALSE); \ + Status = STATUS_SUCCESS; \ + } \ + else \ + { \ + Status = STATUS_UNSUCCESSFUL; \ + } \ +} +#define ChannelClearEvent(Channel, x) \ +{ \ + ASSERT(Channel->x); \ + ASSERT(Channel->x##ObjectBody); \ + ASSERT(Channel->x##WaitObjectBody); \ + if (Channel->x##WaitObjectBody) \ + { \ + KeClearEvent(Channel->x##WaitObjectBody); \ + Status = STATUS_SUCCESS; \ + } \ + else \ + { \ + Status = STATUS_UNSUCCESSFUL; \ + } \ } -#define ChannelUnlock(Channel, x) \ -{ \ - ASSERT((Channel)->x.RefCount == 1); \ - InterlockedDecrement(&(Channel)->x.RefCount); \ - KeReleaseSemaphore( \ - &(Channel)->x.Lock, \ - SEMAPHORE_INCREMENT, \ - 1, \ - FALSE); \ -} +// +// SAC Pool Tags, taken from pooltag.txt: +// +// Rcp? - sacdrv.sys - SAC Driver (Headless) +// RcpA - sacdrv.sys - Internal memory mgr alloc block +// RcpI - sacdrv.sys - Internal memory mgr initial heap block +// RcpS - sacdrv.sys - Security related block +#define GENERIC_TAG '?pcR' +#define ALLOC_BLOCK_TAG 'ApcR' +#define INITIAL_BLOCK_TAG 'IpcR' +#define SECURITY_BLOCK_TAG 'SpcR' +#define FREE_POOL_TAG 'FpcR' +#define GLOBAL_BLOCK_TAG 'GpcR' +#define CHANNEL_BLOCK_TAG 'CpcR' +#define LOCAL_MEMORY_SIGNATURE 'SSEL' +#define GLOBAL_MEMORY_SIGNATURE 'DAEH' -#define ChannelLockOBuffer(Channel) ChannelLock(Channel, ChannelOBufferLock); -#define ChannelUnlockOBuffer(Channel) ChannelUnlock(Channel, ChannelOBufferLock); -#define ChannelLockIBuffer(Channel) ChannelLock(Channel, ChannelIBufferLock); -#define ChannelUnlockIBuffer(Channel) ChannelUnlock(Channel, ChannelIBufferLock); -#define ChannelLockAttributes(Channel) ChannelLock(Channel, ChannelAttributesLock); -#define ChannelUnlockAttributes(Channel) ChannelUnlock(Channel, ChannelAttributesLock); +// +// Size Definitions +// +#define SAC_MEMORY_LIST_SIZE (1 * 1024 * 1024) // 1MB +#define SAC_OBUFFER_SIZE (2 * 1024) // 2KB +#define SAC_CHANNEL_NAME_SIZE 64 +#define SAC_CHANNEL_DESCRIPTION_SIZE 256 +#define SAC_MAX_CHANNELS 10 +#define SAC_SERIAL_PORT_BUFFER_SIZE 1024 // 1KB +#define SAC_MAX_MESSAGES 200 -#define ChannelInitializeEvent(Channel, Attributes, x) \ -{ \ - PVOID Object, WaitObject; \ - if (Attributes->x) \ - { \ - if (!VerifyEventWaitable(Attributes->x, &Object, &WaitObject)) \ - { \ - goto FailChannel; \ - } \ - Channel->x = Attributes->x; \ - Channel->x##ObjectBody = Object; \ - Channel->x##WaitObjectBody = WaitObject; \ - } \ -} - -#define ChannelSetEvent(Channel, x) \ -{ \ - ASSERT(Channel->x); \ - ASSERT(Channel->x##ObjectBody); \ - ASSERT(Channel->x##WaitObjectBody); \ - if (Channel->x) \ - { \ - KeSetEvent(Channel->x, EVENT_INCREMENT, FALSE); \ - Status = STATUS_SUCCESS; \ - } \ - else \ - { \ - Status = STATUS_UNSUCCESSFUL; \ - } \ -} - -#define ChannelClearEvent(Channel, x) \ -{ \ - ASSERT(Channel->x); \ - ASSERT(Channel->x##ObjectBody); \ - ASSERT(Channel->x##WaitObjectBody); \ - if (Channel->x) \ - { \ - KeClearEvent(Channel->x); \ - Status = STATUS_SUCCESS; \ - } \ - else \ - { \ - Status = STATUS_UNSUCCESSFUL; \ - } \ -} - -//Rcp? - sacdrv.sys - SAC Driver (Headless) -//RcpA - sacdrv.sys - Internal memory mgr alloc block -//RcpI - sacdrv.sys - Internal memory mgr initial heap block -//RcpS - sacdrv.sys - Security related block -#define GENERIC_TAG '?pcR' -#define ALLOC_BLOCK_TAG 'ApcR' -#define INITIAL_BLOCK_TAG 'IpcR' -#define SECURITY_BLOCK_TAG 'SpcR' -#define FREE_POOL_TAG 'FpcR' - -#define LOCAL_MEMORY_SIGNATURE 'SSEL' -#define GLOBAL_MEMORY_SIGNATURE 'DAEH' - -#define SAC_MEMORY_LIST_SIZE (1 * 1024 * 1024) - -#define SAC_OBUFFER_SIZE (2 * 1024) - -#define SAC_CHANNEL_FLAG_CLOSE_EVENT 0x2 -#define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT 0x4 -#define SAC_CHANNEL_FLAG_LOCK_EVENT 0x8 -#define SAC_CHANNEL_FLAG_REDRAW_EVENT 0x10 - -typedef struct _SAC_MEMORY_ENTRY -{ - ULONG Signature; - ULONG Tag; - ULONG Size; -} SAC_MEMORY_ENTRY, *PSAC_MEMORY_ENTRY; - -typedef struct _SAC_MEMORY_LIST -{ - ULONG Signature; - PSAC_MEMORY_ENTRY LocalDescriptor; - ULONG Size; - struct _SAC_MEMORY_LIST* Next; -} SAC_MEMORY_LIST, *PSAC_MEMORY_LIST; - -typedef enum _SAC_CHANNEL_TYPE -{ - VtUtf8, - Cmd, - Raw -} SAC_CHANNEL_TYPE; - -typedef enum _SAC_CHANNEL_STATUS -{ - Inactive, - Active -} SAC_CHANNEL_STATUS, *PSAC_CHANNEL_STATUS; - -typedef struct _SAC_CHANNEL_ID -{ - GUID ChannelGuid; - ULONG ChannelId; -} SAC_CHANNEL_ID, *PSAC_CHANNEL_ID; - -typedef struct _SAC_CHANNEL_LOCK -{ - LONG RefCount; - KSEMAPHORE Lock; -} SAC_CHANNEL_LOCK, *PSAC_CHANNEL_LOCK; +// +// Channel flags +// +#define SAC_CHANNEL_FLAG_INTERNAL 0x1 +#define SAC_CHANNEL_FLAG_CLOSE_EVENT 0x2 +#define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT 0x4 +#define SAC_CHANNEL_FLAG_LOCK_EVENT 0x8 +#define SAC_CHANNEL_FLAG_REDRAW_EVENT 0x10 +#define SAC_CHANNEL_FLAG_APPLICATION 0x20 +// +// Forward definitions +// struct _SAC_CHANNEL; +// +// Structures used by the SAC Heap Allocator +// +typedef struct _SAC_MEMORY_ENTRY +{ + ULONG Signature; + ULONG Tag; + ULONG Size; +} SAC_MEMORY_ENTRY, *PSAC_MEMORY_ENTRY; +typedef struct _SAC_MEMORY_LIST +{ + ULONG Signature; + PSAC_MEMORY_ENTRY LocalDescriptor; + ULONG Size; + struct _SAC_MEMORY_LIST* Next; +} SAC_MEMORY_LIST, *PSAC_MEMORY_LIST; + +typedef struct _SAC_MESSAGE_ENTRY +{ + ULONG Index; + PWCHAR Buffer; +} SAC_MESSAGE_ENTRY, *PSAC_MESSAGE_ENTRY; + +// +// SAC supports 3 different channel output types +// +typedef enum _SAC_CHANNEL_TYPE +{ + VtUtf8, + Cmd, + Raw +} SAC_CHANNEL_TYPE; + +// +// A SAC channel can be active or inactive +// +typedef enum _SAC_CHANNEL_STATUS +{ + Inactive, + Active +} SAC_CHANNEL_STATUS, *PSAC_CHANNEL_STATUS; + +// +// A SAC channel identifier +// +typedef struct _SAC_CHANNEL_ID +{ + GUID ChannelGuid; + ULONG ChannelId; +} SAC_CHANNEL_ID, *PSAC_CHANNEL_ID; + +// +// Reference-counted SAC channel semaphore lock +// +typedef struct _SAC_CHANNEL_LOCK +{ + LONG RefCount; + KSEMAPHORE Lock; +} SAC_CHANNEL_LOCK, *PSAC_CHANNEL_LOCK; + +// +// Channel callbacks +// typedef NTSTATUS -(*PSAC_CHANNEL_CREATE)( - IN struct _SAC_CHANNEL* Channel - ); +(NTAPI *PSAC_CHANNEL_CREATE)( + IN struct _SAC_CHANNEL* Channel +); typedef NTSTATUS -(*PSAC_CHANNEL_DESTROY)( - IN struct _SAC_CHANNEL* Channel - ); +(NTAPI *PSAC_CHANNEL_DESTROY)( + IN struct _SAC_CHANNEL* Channel +); typedef NTSTATUS -(*PSAC_CHANNEL_OREAD)( - IN struct _SAC_CHANNEL* Channel, - IN PCHAR Buffer, - IN ULONG BufferSize, - OUT PULONG ByteCount - ); +(NTAPI *PSAC_CHANNEL_OREAD)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + OUT PULONG ByteCount +); typedef NTSTATUS -(*PSAC_CHANNEL_OECHO)( - IN struct _SAC_CHANNEL* Channel, - IN PWCHAR String, - IN ULONG Length - ); +(NTAPI *PSAC_CHANNEL_OECHO)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR String, + IN ULONG Length +); typedef NTSTATUS -(*PSAC_CHANNEL_OFLUSH)( - IN struct _SAC_CHANNEL* Channel - ); +(NTAPI *PSAC_CHANNEL_OFLUSH)( + IN struct _SAC_CHANNEL* Channel +); typedef NTSTATUS -(*PSAC_CHANNEL_OWRITE)( - IN struct _SAC_CHANNEL* Channel, - IN PWCHAR String, - IN ULONG Length - ); +(NTAPI *PSAC_CHANNEL_OWRITE)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR String, + IN ULONG Length +); typedef NTSTATUS -(*PSAC_CHANNEL_IREAD)( - IN struct _SAC_CHANNEL* Channel, - IN PWCHAR Buffer, - IN ULONG BufferSize, - IN PULONG ReturnBufferSize - ); +(NTAPI *PSAC_CHANNEL_IREAD)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN PULONG ReturnBufferSize +); typedef NTSTATUS -(*PSAC_CHANNEL_IBUFFER_FULL)( - IN struct _SAC_CHANNEL* Channel, - OUT PBOOLEAN BufferStatus - ); +(NTAPI *PSAC_CHANNEL_IBUFFER_FULL)( + IN struct _SAC_CHANNEL* Channel, + OUT PBOOLEAN BufferStatus +); typedef -NTSTATUS -(*PSAC_CHANNEL_IBUFFER_LENGTH)( - IN struct _SAC_CHANNEL* Channel - ); +ULONG +(NTAPI *PSAC_CHANNEL_IBUFFER_LENGTH)( + IN struct _SAC_CHANNEL* Channel +); typedef CHAR -(*PSAC_CHANNEL_IREAD_LAST)( - IN struct _SAC_CHANNEL* Channel - ); +(NTAPI *PSAC_CHANNEL_IREAD_LAST)( + IN struct _SAC_CHANNEL* Channel +); typedef NTSTATUS -(*PSAC_CHANNEL_IWRITE)( - IN struct _SAC_CHANNEL* Channel, - IN PCHAR Buffer, - IN ULONG BufferSize - ); +(NTAPI *PSAC_CHANNEL_IWRITE)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR Buffer, + IN ULONG BufferSize +); +// +// A channel and its attributes +// typedef struct _SAC_CHANNEL { - ULONG Index; - SAC_CHANNEL_ID ChannelId; - HANDLE CloseEvent; - PVOID CloseEventObjectBody; - PKEVENT CloseEventWaitObjectBody; - HANDLE HasNewDataEvent; - PVOID HasNewDataEventObjectBody; - PKEVENT HasNewDataEventWaitObjectBody; - HANDLE LockEvent; - PVOID LockEventObjectBody; - PKEVENT LockEventWaitObjectBody; - HANDLE RedrawEvent; - PVOID RedrawEventObjectBody; - PKEVENT RedrawEventWaitObjectBody; - PFILE_OBJECT FileObject; - SAC_CHANNEL_TYPE ChannelType; - SAC_CHANNEL_STATUS ChannelStatus; - WCHAR NameBuffer[64 + 1]; - WCHAR DescriptionBuffer[256 + 1]; - ULONG Flags; - GUID ApplicationType; - BOOLEAN WriteEnabled; - ULONG IBufferIndex; - PVOID IBuffer; - BOOLEAN ChannelHasNewIBufferData; - UCHAR CursorRow; - UCHAR CursorCol; - UCHAR CursorY; - UCHAR CursorX; - UCHAR CursorVisible; - PVOID OBuffer; - ULONG OBufferIndex; - ULONG OBufferFirstGoodIndex; - BOOLEAN ChannelHasNewOBufferData; - PSAC_CHANNEL_CREATE ChannelCreate; - PSAC_CHANNEL_DESTROY ChannelDestroy; - PSAC_CHANNEL_OFLUSH OBufferFlush; - PSAC_CHANNEL_OECHO OBufferEcho; - PSAC_CHANNEL_OWRITE OBufferWrite; - PSAC_CHANNEL_OREAD OBufferRead; - PSAC_CHANNEL_OWRITE IBufferWrite; - PSAC_CHANNEL_IREAD IBufferRead; - PSAC_CHANNEL_IREAD_LAST IBufferReadLast; - PSAC_CHANNEL_IBUFFER_FULL IBufferIsFull; - PSAC_CHANNEL_IBUFFER_LENGTH IBufferLength; - SAC_CHANNEL_LOCK ChannelAttributeLock; - SAC_CHANNEL_LOCK ChannelOBufferLock; - SAC_CHANNEL_LOCK ChannelIBufferLock; + LONG Index; + SAC_CHANNEL_ID ChannelId; + HANDLE CloseEvent; + PVOID CloseEventObjectBody; + PKEVENT CloseEventWaitObjectBody; + HANDLE HasNewDataEvent; + PVOID HasNewDataEventObjectBody; + PKEVENT HasNewDataEventWaitObjectBody; + HANDLE LockEvent; + PVOID LockEventObjectBody; + PKEVENT LockEventWaitObjectBody; + HANDLE RedrawEvent; + PVOID RedrawEventObjectBody; + PKEVENT RedrawEventWaitObjectBody; + PFILE_OBJECT FileObject; + SAC_CHANNEL_TYPE ChannelType; + SAC_CHANNEL_STATUS ChannelStatus; + WCHAR NameBuffer[SAC_CHANNEL_NAME_SIZE + 1]; + WCHAR DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE + 1]; + ULONG Flags; + GUID ApplicationType; + LONG WriteEnabled; + ULONG IBufferIndex; + PCHAR IBuffer; + LONG ChannelHasNewIBufferData; + UCHAR CursorRow; + UCHAR CursorCol; + UCHAR CursorY; + UCHAR CursorX; + UCHAR CursorVisible; + PCHAR OBuffer; + ULONG OBufferIndex; + ULONG OBufferFirstGoodIndex; + LONG ChannelHasNewOBufferData; + PSAC_CHANNEL_CREATE ChannelCreate; + PSAC_CHANNEL_DESTROY ChannelDestroy; + PSAC_CHANNEL_OFLUSH ChannelOutputFlush; + PSAC_CHANNEL_OECHO ChannelOutputEcho; + PSAC_CHANNEL_OWRITE ChannelOutputWrite; + PSAC_CHANNEL_OREAD ChannelOutputRead; + PSAC_CHANNEL_IWRITE ChannelInputWrite; + PSAC_CHANNEL_IREAD ChannelInputRead; + PSAC_CHANNEL_IREAD_LAST ChannelInputReadLast; + PSAC_CHANNEL_IBUFFER_FULL ChannelInputBufferIsFull; + PSAC_CHANNEL_IBUFFER_LENGTH ChannelInputBufferLength; + SAC_CHANNEL_LOCK ChannelAttributeLock; + SAC_CHANNEL_LOCK ChannelOBufferLock; + SAC_CHANNEL_LOCK ChannelIBufferLock; } SAC_CHANNEL, *PSAC_CHANNEL; -typedef struct _SAC_DEVICE_EXTENSION -{ - PDEVICE_OBJECT DeviceObject; - BOOLEAN Initialized; - BOOLEAN Rundown; - BOOLEAN PriorityFail; - KPRIORITY PriorityBoost; - PEPROCESS Process; - KSPIN_LOCK Lock; - KEVENT RundownEvent; - KEVENT Event; - HANDLE WorkerThreadHandle; - KEVENT WorkerThreadEvent; - KTIMER Timer; - KDPC Dpc; - LIST_ENTRY List; -} SAC_DEVICE_EXTENSION, *PSAC_DEVICE_EXTENSION; - typedef struct _SAC_CHANNEL_ATTRIBUTES { - SAC_CHANNEL_TYPE ChannelType; - WCHAR NameBuffer[64 + 1]; - WCHAR DescriptionBuffer[256 + 1]; - ULONG Flag; - PKEVENT CloseEvent; - PKEVENT HasNewDataEvent; - PKEVENT LockEvent; - PKEVENT RedrawEvent; - GUID ChannelId; + SAC_CHANNEL_TYPE ChannelType; + WCHAR NameBuffer[64 + 1]; + WCHAR DescriptionBuffer[256 + 1]; + ULONG Flag; + HANDLE CloseEvent; + HANDLE HasNewDataEvent; + HANDLE LockEvent; + HANDLE RedrawEvent; + GUID ChannelId; } SAC_CHANNEL_ATTRIBUTES, *PSAC_CHANNEL_ATTRIBUTES; +// +// Cached Machine Information +// +typedef struct _SAC_MACHINE_INFO +{ + PWCHAR MachineName; + PWCHAR MachineGuid; + PWCHAR ProcessorArchitecture; + PWCHAR MajorVersion; + PWCHAR BuildNumber; + PWCHAR ProductType; + PWCHAR ServicePack; +} SAC_MACHINE_INFO, *PSAC_MACHINE_INFO; + +// +// The device extension for the SAC +// +typedef struct _SAC_DEVICE_EXTENSION +{ + PDEVICE_OBJECT DeviceObject; + BOOLEAN Initialized; + BOOLEAN Rundown; + BOOLEAN PriorityFail; + BOOLEAN RundownInProgress; + KPRIORITY PriorityBoost; + PEPROCESS Process; + KSPIN_LOCK Lock; + KEVENT RundownEvent; + KEVENT Event; + HANDLE WorkerThreadHandle; + KEVENT WorkerThreadEvent; + KTIMER Timer; + KDPC Dpc; + LIST_ENTRY List; +} SAC_DEVICE_EXTENSION, *PSAC_DEVICE_EXTENSION; + +// +// Dispatch Routines +// NTSTATUS +NTAPI Dispatch( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ); NTSTATUS NTAPI DispatchDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ); NTSTATUS +NTAPI DispatchShutdownControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ); VOID +NTAPI UnloadHandler( - IN PDRIVER_OBJECT DriverObject + IN PDRIVER_OBJECT DriverObject +); + +// +// Initialization and shutdown routines +// +VOID +NTAPI +FreeGlobalData( + VOID ); VOID -FreeGlobalData( - VOID +NTAPI +FreeDeviceData( + IN PDEVICE_OBJECT DeviceObject ); BOOLEAN +NTAPI InitializeDeviceData( - IN PDEVICE_OBJECT DeviceObject + IN PDEVICE_OBJECT DeviceObject ); BOOLEAN +NTAPI InitializeGlobalData( - IN PUNICODE_STRING RegistryPath, - IN PDRIVER_OBJECT DriverObject + IN PUNICODE_STRING RegistryPath, + IN PDRIVER_OBJECT DriverObject ); -extern ULONG SACDebug; +BOOLEAN +NTAPI +InitializeMemoryManagement( + VOID +); +VOID +NTAPI +FreeMemoryManagement( + VOID +); + +VOID +NTAPI +InitializeCmdEventInfo( + VOID +); + +VOID +NTAPI +InitializeMachineInformation( + VOID +); + +NTSTATUS +NTAPI +PreloadGlobalMessageTable( + IN PVOID ImageBase +); + +NTSTATUS +NTAPI +TearDownGlobalMessageTable( + VOID +); + +NTSTATUS +NTAPI +GetCommandConsoleLaunchingPermission( + OUT PBOOLEAN Permission +); + +NTSTATUS +NTAPI +ImposeSacCmdServiceStartTypePolicy( + VOID +); + +NTSTATUS +NTAPI +RegisterBlueScreenMachineInformation( + VOID +); + +VOID +NTAPI +FreeMachineInformation( + VOID +); + +// +// DPC, Timer, Thread Callbacks +// +VOID +NTAPI +TimerDpcRoutine( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 +); + +// +// Custom SAC Heap Allocator Routines +// +PVOID +NTAPI +MyAllocatePool( + IN SIZE_T PoolSize, + IN ULONG Tag, + IN PCHAR File, + IN ULONG Line +); + +VOID +NTAPI +MyFreePool( + IN PVOID *Block +); + +// +// Connection Manager Routines +// +NTSTATUS +NTAPI +ConMgrInitialize( + VOID +); + +VOID +NTAPI +ConMgrWorkerProcessEvents( + IN PSAC_DEVICE_EXTENSION DeviceExtension +); + +NTSTATUS +NTAPI +ConMgrShutdown( + VOID +); + +BOOLEAN +NTAPI +ConMgrSimpleEventMessage( + IN ULONG MessageIndex, + IN BOOLEAN LockHeld +); + +BOOLEAN +NTAPI +SacPutSimpleMessage( + IN ULONG MessageIndex +); + +VOID +NTAPI +SacPutString( + IN PWCHAR String +); + +NTSTATUS +NTAPI +ConMgrWriteData( + IN PSAC_CHANNEL Channel, + IN PVOID Buffer, + IN ULONG BufferLength +); + +NTSTATUS +NTAPI +ConMgrFlushData( + IN PSAC_CHANNEL Channel +); + +BOOLEAN +NTAPI +ConMgrIsWriteEnabled( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ConMgrHandleEvent( + IN ULONG EventCode, + IN PSAC_CHANNEL Channel, + OUT PVOID Data +); + +// +// Channel Manager Routines +// +NTSTATUS +NTAPI +ChanMgrInitialize( + VOID +); + +NTSTATUS +NTAPI +ChanMgrShutdown( + VOID +); + +NTSTATUS +NTAPI +ChanMgrCreateChannel( + OUT PSAC_CHANNEL *Channel, + IN PSAC_CHANNEL_ATTRIBUTES Attributes +); + +NTSTATUS +NTAPI +ChanMgrGetByHandle( + IN SAC_CHANNEL_ID ChannelId, + OUT PSAC_CHANNEL* TargetChannel +); + +NTSTATUS +NTAPI +ChanMgrReleaseChannel( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChanMgrGetNextActiveChannel( + IN PSAC_CHANNEL CurrentChannel, + IN PULONG TargetIndex, + OUT PSAC_CHANNEL *TargetChannel +); + +NTSTATUS +NTAPI +ChanMgrCloseChannel( + IN PSAC_CHANNEL Channel +); + +// +// Channel Routines +// +NTSTATUS +NTAPI +ChannelClose( + IN PSAC_CHANNEL Channel +); + +BOOLEAN +NTAPI +ChannelIsEqual( + IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ID ChannelId +); + +NTSTATUS +NTAPI +ChannelOWrite( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize +); + +NTSTATUS +NTAPI +ChannelOFlush( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChannelSetRedrawEvent( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChannelClearRedrawEvent( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChannelHasRedrawEvent( + IN PSAC_CHANNEL Channel, + OUT PBOOLEAN Present +); + +BOOLEAN +NTAPI +ChannelIsActive( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChannelGetName( + IN PSAC_CHANNEL Channel, + OUT PWCHAR *Name +); + +BOOLEAN +NTAPI +ChannelIsEqual( + IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ID ChannelId +); + +NTSTATUS +NTAPI +ChannelCreate( + IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ATTRIBUTES Attributes, + IN SAC_CHANNEL_ID ChannelId +); + +NTSTATUS +NTAPI +ChannelDestroy( + IN PSAC_CHANNEL Channel +); + +// +// RAW Channel Table +// +NTSTATUS +NTAPI +RawChannelCreate( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +RawChannelDestroy( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +RawChannelORead( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + OUT PULONG ByteCount +); + +NTSTATUS +NTAPI +RawChannelOEcho( + IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length +); + +NTSTATUS +NTAPI +RawChannelOFlush( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +RawChannelOWrite( + IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length +); + +NTSTATUS +NTAPI +RawChannelIRead( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN PULONG ReturnBufferSize +); + +NTSTATUS +NTAPI +RawChannelIBufferIsFull( + IN PSAC_CHANNEL Channel, + OUT PBOOLEAN BufferStatus +); + +ULONG +NTAPI +RawChannelIBufferLength( + IN PSAC_CHANNEL Channel +); + +CHAR +NTAPI +RawChannelIReadLast( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +RawChannelIWrite( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize +); + +// +// Helper Routines +// +NTSTATUS +NTAPI +SerialBufferGetChar( + OUT PCHAR Char +); + +NTSTATUS +NTAPI +UTF8EncodeAndSend( + IN PWCHAR String +); + +NTSTATUS +NTAPI +TranslateMachineInformationXML( + IN PWCHAR *Buffer, + IN PWCHAR ExtraData +); + +PWCHAR +NTAPI +GetMessage( + IN ULONG MessageIndex +); + +BOOLEAN +NTAPI +VerifyEventWaitable( + IN HANDLE Handle, + OUT PVOID *WaitObject, + OUT PVOID *ActualWaitObject +); + +// +// SAC Command Functions +// +VOID +NTAPI +DoRebootCommand( + IN BOOLEAN Reboot +); + +// +// External data +// +extern ULONG SACDebug; +extern PSAC_MESSAGE_ENTRY GlobalMessageTable; +extern KMUTEX CurrentChannelLock; +extern LONG CurrentChannelRefCount; +extern PCHAR SerialPortBuffer; +extern PCHAR Utf8ConversionBuffer; +extern ULONG Utf8ConversionBufferSize; + +// +// Function to initailize a SAC Semaphore Lock +// +FORCEINLINE +VOID +SacInitializeLock(IN PSAC_CHANNEL_LOCK Lock) +{ + KeInitializeSemaphore(&Lock->Lock, 1, 1); +} + +// +// Function to acquire a SAC Semaphore Lock +// +FORCEINLINE +VOID +SacAcquireLock(IN PSAC_CHANNEL_LOCK Lock) +{ + KeWaitForSingleObject(&Lock->Lock, Executive, KernelMode, FALSE, NULL); + ASSERT(Lock->RefCount == 0); + _InterlockedIncrement(&Lock->RefCount); +} + +// +// Function to release a SAC Semaphore Lock +// +FORCEINLINE +VOID +SacReleaseLock(IN PSAC_CHANNEL_LOCK Lock) +{ + ASSERT(Lock->RefCount == 1); + _InterlockedDecrement(&Lock->RefCount); + KeReleaseSemaphore(&Lock->Lock, SEMAPHORE_INCREMENT, 1, FALSE); +} + +// +// Function to check if the SAC Mutex Lock is held +// +FORCEINLINE +VOID +SacAssertMutexLockHeld(VOID) +{ + ASSERT(CurrentChannelRefCount == 1); + ASSERT(KeReadStateMutex(&CurrentChannelLock) == 0); +} + +// +// Function to check if the SAC Mutex Lock is held +// +FORCEINLINE +VOID +SacInitializeMutexLock(VOID) +{ + KeInitializeMutex(&CurrentChannelLock, 0); + CurrentChannelRefCount = 0; +} + +// +// Function to acquire the SAC Mutex Lock +// +FORCEINLINE +VOID +SacAcquireMutexLock(VOID) +{ + KeWaitForSingleObject(&CurrentChannelLock, Executive, KernelMode, FALSE, NULL); + ASSERT(CurrentChannelRefCount == 0); + _InterlockedIncrement(&CurrentChannelRefCount); +} + +// +// Function to release the SAC Mutex Lock +// +FORCEINLINE +VOID +SacReleaseMutexLock(VOID) +{ + ASSERT(CurrentChannelRefCount == 1); + _InterlockedDecrement(&CurrentChannelRefCount); + KeReleaseMutex(&CurrentChannelLock, FALSE); +} + +// +// Locking Macros +// +#define ChannelLockCreates() SacAcquireLock(&ChannelCreateLock); +#define ChannelUnlockCreates() SacReleaseLock(&ChannelCreateLock); +#define ChannelLockOBuffer(x) SacAcquireLock(&x->ChannelOBufferLock); +#define ChannelUnlockOBuffer(x) SacReleaseLock(&x->ChannelOBufferLock); +#define ChannelLockIBuffer(x) SacAcquireLock(&x->ChannelIBufferLock); +#define ChannelUnlockIBuffer(x) SacReleaseLock(&x->ChannelIBufferLock); +#define ChannelLockAttributes(x) SacAcquireLock(&x->ChannelAttributeLock); +#define ChannelUnlockAttributes(x) SacReleaseLock(&x->ChannelAttributeLock); +#define ChannelSlotLock(x) SacAcquireLock(&ChannelSlotLock[x]); +#define ChannelSlotUnlock(x) SacReleaseLock(&ChannelSlotLock[x]); + +// +// Channel Accessors +// +FORCEINLINE +ULONG +ChannelGetFlags(IN PSAC_CHANNEL Channel) +{ + return Channel->Flags; +} + +FORCEINLINE +LONG +ChannelGetIndex(IN PSAC_CHANNEL Channel) +{ + /* Return the index of the channel */ + return Channel->Index; +} diff --git a/reactos/drivers/sac/driver/sacdrv.rc b/reactos/drivers/sac/driver/sacdrv.rc index ceb819a9005..1c1e27d36ec 100644 --- a/reactos/drivers/sac/driver/sacdrv.rc +++ b/reactos/drivers/sac/driver/sacdrv.rc @@ -1,5 +1,5 @@ /* - * PROJECT: ReactOS Boot Loader + * PROJECT: ReactOS Drivers * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: drivers/base/sac/driver/sacdrv.rc * PURPOSE: Resource File for EMS SAC Driver diff --git a/reactos/drivers/sac/driver/util.c b/reactos/drivers/sac/driver/util.c index b40f058c592..f536915e23f 100644 --- a/reactos/drivers/sac/driver/util.c +++ b/reactos/drivers/sac/driver/util.c @@ -1,18 +1,759 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/util.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/util.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +PCHAR Utf8ConversionBuffer; +ULONG Utf8ConversionBufferSize; +PSAC_MACHINE_INFO MachineInformation; +PVOID RequestSacCmdEventObjectBody; +PKEVENT RequestSacCmdEventWaitObjectBody; +PVOID RequestSacCmdSuccessEventObjectBody; +PKEVENT RequestSacCmdSuccessEventWaitObjectBody; +PVOID RequestSacCmdFailureEventObjectBody; +PKEVENT RequestSacCmdFailureEventWaitObjectBody; +PFILE_OBJECT ServiceProcessFileObject; +BOOLEAN HaveUserModeServiceCmdEventInfo; + +PSAC_MESSAGE_ENTRY GlobalMessageTable; +ULONG GlobalMessageTableCount; + +LONG SerialPortConsumerIndex, SerialPortProducerIndex; +PCHAR SerialPortBuffer; + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +SacTranslateUnicodeToUtf8(IN PWCHAR SourceBuffer, + IN ULONG SourceBufferLength, + OUT PCHAR DestinationBuffer, + IN ULONG DestinationBufferSize, + OUT PULONG UTF8Count, + OUT PULONG ProcessedCount) +{ + ASSERT(FALSE); + return FALSE; +} + +PWCHAR +NTAPI +GetMessage(IN ULONG MessageIndex) +{ + PSAC_MESSAGE_ENTRY MessageEntry; + ULONG i; + PWCHAR MessageData = NULL; + + /* Loop all cached messages */ + for (i = 0; i < GlobalMessageTableCount; i++) + { + /* Check if this one matches the index */ + MessageEntry = &GlobalMessageTable[i]; + if (MessageEntry->Index == MessageIndex) + { + /* It does, return the buffer */ + MessageData = MessageEntry->Buffer; + break; + } + } + + /* We should always find it */ + if (!MessageData) ASSERT(FALSE); + return MessageData; +} + +NTSTATUS +NTAPI +UTF8EncodeAndSend(IN PWCHAR String) +{ + ULONG ProcessedCount, Utf8Count, i; + NTSTATUS Status = STATUS_SUCCESS; + + /* Call the translator routine */ + if (SacTranslateUnicodeToUtf8(String, + wcslen(String), + Utf8ConversionBuffer, + Utf8ConversionBufferSize, + &Utf8Count, + &ProcessedCount)) + { + /* Loop every character */ + for (i = 0; i < Utf8Count; i++) + { + /* Send it to the terminal */ + Status = HeadlessDispatch(HeadlessCmdPutData, + &Utf8ConversionBuffer[i], + sizeof(Utf8ConversionBuffer[i]), + NULL, + NULL); + if (!NT_SUCCESS(Status)) break; + } + } + else + { + /* Conversion failed */ + Status = STATUS_UNSUCCESSFUL; + } + + /* All done */ + return Status; +} + +VOID +NTAPI +SacFormatMessage(IN PWCHAR FormattedString, + IN PWCHAR MessageString, + IN ULONG MessageSize) +{ + /* FIXME: For now don't format anything */ + wcsncpy(FormattedString, MessageString, MessageSize / sizeof(WCHAR)); +} + +NTSTATUS +NTAPI +PreloadGlobalMessageTable(IN PVOID ImageBase) +{ + NTSTATUS Status; + ULONG MessageId, TotalLength, TextSize, i; + PWCHAR StringBuffer; + PMESSAGE_RESOURCE_ENTRY MessageEntry; + PAGED_CODE(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC PreloadGlobalMessageTable: Entering.\n"); + + /* Nothing to do if we already have a table */ + if (GlobalMessageTable) goto Exit; + + /* Loop through up to 200 messages */ + for (MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) + { + /* Find this message ID in the string table*/ + Status = RtlFindMessage(ImageBase, + 11, + LANG_NEUTRAL, + MessageId, + &MessageEntry); + if (NT_SUCCESS(Status)) + { + /* Make sure it's Unicode */ + ASSERT(MessageEntry->Flags & MESSAGE_RESOURCE_UNICODE); + + /* Remove the space taken up by the OS header, and add our own */ + TotalLength += MessageEntry->Length - + FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text) + + sizeof(SAC_MESSAGE_ENTRY); + + /* One more in the table */ + GlobalMessageTableCount++; + } + } + + /* We should've found at least one message... */ + if (!TotalLength) + { + /* Bail out otherwise */ + SAC_DBG(SAC_DBG_INIT, "SAC PreloadGlobalMessageTable: No Messages.\n"); + Status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + /* Allocate space for the buffers and headers */ + GlobalMessageTable = SacAllocatePool(TotalLength, GLOBAL_BLOCK_TAG); + if (!GlobalMessageTable) + { + /* Bail out if we couldn't allocate it */ + Status = STATUS_NO_MEMORY; + goto Exit; + } + + /* All the buffers are going to be at the end of the table */ + StringBuffer = (PWCHAR)(&GlobalMessageTable[GlobalMessageTableCount]); + + /* Now loop over our entries again */ + for (i = 0, MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) + { + /* Make sure the message is still there...! */ + Status = RtlFindMessage(ImageBase, + 11, + LANG_NEUTRAL, + MessageId, + &MessageEntry); + if (NT_SUCCESS(Status)) + { + /* Write the entry in the message table*/ + GlobalMessageTable[i].Index = MessageId; + GlobalMessageTable[i].Buffer = StringBuffer; + + /* The structure includes the size of the header, elide it */ + TextSize = MessageEntry->Length - + FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text); + + /* Format the message into the entry. It should be same or smaller */ + SacFormatMessage(StringBuffer, (PWCHAR)MessageEntry->Text, TextSize); + ASSERT((ULONG)(wcslen(StringBuffer)*sizeof(WCHAR)) <= TextSize); + + /* Move to the next buffer space */ + StringBuffer += TextSize; + + /* Move to the next entry, make sure the status is full success */ + i++; + Status = STATUS_SUCCESS; + } + } + +Exit: + /* All done, return the status code */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Exiting with status 0x%0x\n", Status); + return Status; +} + +NTSTATUS +NTAPI +TearDownGlobalMessageTable(VOID) +{ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Entering.\n"); + + /* Free the table if one existed */ + if (GlobalMessageTable) SacFreePool(GlobalMessageTable); + + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Exiting\n"); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +TranslateMachineInformationXML(IN PWCHAR *Buffer, + IN PWCHAR ExtraData) +{ + NTSTATUS Status; + ULONG Size; + PWCHAR p; + CHECK_PARAMETER1(Buffer); + + Status = STATUS_SUCCESS; + Size = wcslen(L"\r\n"); + + if (MachineInformation->MachineName) + { + Size += wcslen(MachineInformation->MachineName); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->MachineGuid) + { + Size += wcslen(MachineInformation->MachineGuid); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->ProcessorArchitecture) + { + Size += wcslen(MachineInformation->ProcessorArchitecture); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->MajorVersion) + { + Size += wcslen(MachineInformation->MajorVersion); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->BuildNumber) + { + Size += wcslen(MachineInformation->BuildNumber); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->ProductType) + { + Size += wcslen(MachineInformation->ProductType); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->ServicePack) + { + Size += wcslen(MachineInformation->ServicePack); + Size += wcslen(L"%s\r\n"); + } + + if (ExtraData) Size += wcslen(ExtraData); + + Size += wcslen(L"\r\n"); + + p = (PWCHAR)SacAllocatePool((Size + sizeof(ANSI_NULL)) * sizeof(WCHAR), GLOBAL_BLOCK_TAG); + + *Buffer = p; + if (!p) return STATUS_NO_MEMORY; + + Size = wcslen(L"\r\n"); + wcscpy(p, L"\r\n"); + + p += Size; + + if (MachineInformation->MachineName) + { + p += swprintf(p, L"%s\r\n", MachineInformation->MachineName); + } + + if (MachineInformation->MachineGuid) + { + p += swprintf(p, L"%s\r\n", MachineInformation->MachineGuid); + } + + if (MachineInformation->ProcessorArchitecture) + { + p += swprintf(p, L"%s\r\n", MachineInformation->ProcessorArchitecture); + } + + if (MachineInformation->MajorVersion) + { + p += swprintf(p, L"%s\r\n", MachineInformation->MajorVersion); + } + + if (MachineInformation->BuildNumber) + { + p += swprintf(p, L"%s\r\n", MachineInformation->BuildNumber); + } + + if (MachineInformation->ProductType) + { + p += swprintf(p, L"%s\r\n", MachineInformation->ProductType); + } + + if (MachineInformation->ServicePack) + { + p += swprintf(p, L"%s\r\n", MachineInformation->ServicePack); + } + + if (ExtraData) + { + Size = wcslen(ExtraData); + wcscpy(p, ExtraData); + p += Size; + } + + wcscpy(p, L"\r\n"); + ASSERT((((ULONG) wcslen(*Buffer) + 1) * sizeof(WCHAR)) <= Size); + return Status; +} + +VOID +NTAPI +InitializeMachineInformation(VOID) +{ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Entering.\n"); + + /* FIXME: TODO */ + MachineInformation = NULL; + ASSERT(FALSE); + + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Exiting with error.\n"); +} + +NTSTATUS +NTAPI +GetRegistryValueBuffer(IN PCWSTR KeyName, + IN PWCHAR ValueName, + IN PKEY_VALUE_PARTIAL_INFORMATION* Buffer) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING DestinationString; + HANDLE Handle; + SIZE_T ResultLength = 0; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: Entering.\n"); + CHECK_PARAMETER1(KeyName); + CHECK_PARAMETER2(ValueName); + + /* Open the specified key */ + RtlInitUnicodeString(&DestinationString, KeyName); + InitializeObjectAttributes(&ObjectAttributes, + &DestinationString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenKey(&Handle, + KEY_WRITE | SYNCHRONIZE | KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + /* Bail out on failure */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed ZwOpenKey: %X.\n", Status); + return Status; + } + + /* Query the size of the key */ + RtlInitUnicodeString(&DestinationString, ValueName); + Status = ZwQueryValueKey(Handle, + &DestinationString, + KeyValuePartialInformation, + NULL, + 0, + &ResultLength); + if (!ResultLength) return Status; + + /* Allocate the buffer for the partial info structure and our integer data */ + ResultLength += sizeof(ULONG); + *Buffer = SacAllocatePool(ResultLength, GLOBAL_BLOCK_TAG); + if (!*Buffer) + { + SAC_DBG(1, "SAC GetRegistryValueBuffer: failed allocation\n"); + return Status; + } + + /* Now read the data */ + Status = ZwQueryValueKey(Handle, + &DestinationString, + KeyValuePartialInformation, + *Buffer, + ResultLength, + &ResultLength); + if (!NT_SUCCESS(Status)) + { + /* Free the buffer if we couldn't read the data */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed ZwQueryValueKey: %X.\n", Status); + SacFreePool(*Buffer); + } + + /* Return the result */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Exiting.\n"); + return Status; +} + +NTSTATUS +NTAPI +SetRegistryValue(IN PCWSTR KeyName, + IN PWCHAR ValueName, + IN ULONG Type, + IN PVOID Data, + IN ULONG DataSize) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING DestinationString; + HANDLE Handle; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Entering.\n"); + CHECK_PARAMETER1(KeyName); + CHECK_PARAMETER2(ValueName); + CHECK_PARAMETER4(Data); + + /* Open the specified key */ + RtlInitUnicodeString(&DestinationString, KeyName); + InitializeObjectAttributes(&ObjectAttributes, + &DestinationString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenKey(&Handle, + KEY_WRITE | SYNCHRONIZE | KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + /* Bail out on failure */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: failed ZwOpenKey: %X.\n", Status); + return Status; + } + + /* Set the specified value */ + RtlInitUnicodeString(&DestinationString, ValueName); + Status = ZwSetValueKey(Handle, &DestinationString, 0, Type, Data, DataSize); + if (!NT_SUCCESS(Status)) + { + /* Print error on failure */ + SAC_DBG(1, "SAC SetRegistryValue: failed ZwSetValueKey: %X.\n", Status); + } + + /* Close the handle and exit */ + NtClose(Handle); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Exiting.\n"); + return Status; +} + +NTSTATUS +NTAPI +CopyRegistryValueData(IN PULONG* Buffer, + IN PKEY_VALUE_PARTIAL_INFORMATION PartialInfo) +{ + NTSTATUS Status = STATUS_SUCCESS; + CHECK_PARAMETER1(Buffer); + CHECK_PARAMETER2(PartialInfo); + + /* Allocate space for registry data */ + *Buffer = SacAllocatePool(PartialInfo->DataLength, GLOBAL_BLOCK_TAG); + if (*Buffer) + { + /* Copy the data into the buffer */ + RtlCopyMemory(*Buffer, PartialInfo->Data, PartialInfo->DataLength); + } + else + { + /* Set the correct error code */ + SAC_DBG(SAC_DBG_UTIL, "SAC CopyRegistryValueBuffer: Failed ALLOCATE.\n"); + Status = STATUS_NO_MEMORY; + } + + /* Return the result */ + return Status; +} + +NTSTATUS +NTAPI +GetCommandConsoleLaunchingPermission(OUT PBOOLEAN Permission) +{ + NTSTATUS Status; + PKEY_VALUE_PARTIAL_INFORMATION Dummy; + + /* Assume success and read the key */ + *Permission = TRUE; + Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacdrv", + L"DisableCmdSessions", + &Dummy); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + /* The default is success */ + Status = STATUS_SUCCESS; + } + else + { + /* Only if the key is present and set, do we disable permission */ + if (NT_SUCCESS(Status)) *Permission = FALSE; + } + + /* Return status */ + return Status; +} + +NTSTATUS +NTAPI +ImposeSacCmdServiceStartTypePolicy(VOID) +{ + NTSTATUS Status; + PKEY_VALUE_PARTIAL_INFORMATION Buffer = NULL; + PULONG Data; + + /* Read the service start type*/ + Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacsvr", + L"Start", + &Buffer); + if (!NT_SUCCESS(Status)) return Status; + + /* If there's no start type, fail, as this is unusual */ + if (!Buffer) return STATUS_UNSUCCESSFUL; + + /* Read the value */ + Status = CopyRegistryValueData(&Data, Buffer); + SacFreePool(Buffer); + if (!NT_SUCCESS(Status)) return Status; + + /* Check what the current start type is */ + switch (*Data) + { + /* It's boot, system, or disabled */ + case 1: + case 2: + case 4: + /* Leave it as is */ + return Status; + + case 3: + + /* It's set to automatic, set it to system instead */ + *Data = 2; + Status = SetRegistryValue(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacsvr", + L"Start", + REG_DWORD, + Data, + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC ImposeSacCmdServiceStartTypePolicy: Failed SetRegistryValue: %X\n", Status); + } + break; + + default: + ASSERT(FALSE); + } + + return Status; +} + +VOID +NTAPI +InitializeCmdEventInfo(VOID) +{ + /* Check if we were already initailized */ + if (HaveUserModeServiceCmdEventInfo) + { + /* Full state expected */ + ASSERT(RequestSacCmdEventObjectBody); + ASSERT(RequestSacCmdSuccessEventObjectBody); + ASSERT(RequestSacCmdFailureEventObjectBody); + + /* Dereference each wait object in turn */ + if (RequestSacCmdEventObjectBody) + { + ObDereferenceObject(RequestSacCmdEventObjectBody); + } + + if (RequestSacCmdSuccessEventObjectBody) + { + ObDereferenceObject(RequestSacCmdSuccessEventObjectBody); + } + + if (RequestSacCmdFailureEventObjectBody) + { + ObDereferenceObject(RequestSacCmdFailureEventObjectBody); + } + } + + /* Claer everything */ + RequestSacCmdEventObjectBody = NULL; + RequestSacCmdEventWaitObjectBody = NULL; + RequestSacCmdSuccessEventObjectBody = NULL; + RequestSacCmdSuccessEventWaitObjectBody = NULL; + RequestSacCmdFailureEventObjectBody = NULL; + RequestSacCmdFailureEventWaitObjectBody = NULL; + ServiceProcessFileObject = NULL; + + /* Reset state */ + HaveUserModeServiceCmdEventInfo = FALSE; +} + +NTSTATUS +NTAPI +RegisterBlueScreenMachineInformation(VOID) +{ + PWCHAR XmlBuffer; + PHEADLESS_BLUE_SCREEN_DATA BsBuffer; + ULONG Length, HeaderLength, TotalLength; + NTSTATUS Status; + ULONG i; + + /* Create the XML buffer and make sure it's OK */ + Status = TranslateMachineInformationXML(&XmlBuffer, NULL); + CHECK_PARAMETER_WITH_STATUS(NT_SUCCESS(Status), Status); + CHECK_PARAMETER_WITH_STATUS(XmlBuffer, STATUS_UNSUCCESSFUL); + + /* Compute the sizes and allocate a buffer for it */ + Length = wcslen(XmlBuffer); + HeaderLength = strlen("MACHINEINFO"); + TotalLength = HeaderLength + + Length + + sizeof(*BsBuffer) + + 2 * sizeof(ANSI_NULL); + BsBuffer = SacAllocatePool(TotalLength, GLOBAL_BLOCK_TAG); + CHECK_PARAMETER_WITH_STATUS(BsBuffer, STATUS_NO_MEMORY); + + /* Copy the XML property name */ + strcpy((PCHAR)BsBuffer->XMLData, "MACHINEINFO"); + BsBuffer->Property = (PUCHAR)HeaderLength + sizeof(ANSI_NULL); + + /* Copy the data and NULL-terminate it */ + for (i = 0; i < Length; i++) + { + BsBuffer->XMLData[HeaderLength + sizeof(ANSI_NULL) + i] = XmlBuffer[i]; + } + BsBuffer->XMLData[HeaderLength + sizeof(ANSI_NULL) + i] = ANSI_NULL; + + /* Let the OS save the buffer for later */ + Status = HeadlessDispatch(HeadlessCmdSetBlueScreenData, + BsBuffer, + TotalLength, + NULL, + NULL); + + /* Failure or not, we don't need this anymore */ + SacFreePool(BsBuffer); + SacFreePool(XmlBuffer); + + /* Return the result */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information: Exiting.\n"); + return Status; +} + +VOID +NTAPI +FreeMachineInformation(VOID) +{ + ASSERT(MachineInformation); + + /* Free every cached string of machine information */ + if (MachineInformation->MachineName) SacFreePool(MachineInformation); + if (MachineInformation->MachineGuid) SacFreePool(MachineInformation->MachineGuid); + if (MachineInformation->ProcessorArchitecture) SacFreePool(MachineInformation->ProcessorArchitecture); + if (MachineInformation->MajorVersion) SacFreePool(MachineInformation->MajorVersion); + if (MachineInformation->BuildNumber) SacFreePool(MachineInformation->BuildNumber); + if (MachineInformation->ProductType) SacFreePool(MachineInformation->ProductType); + if (MachineInformation->ServicePack) SacFreePool(MachineInformation->ServicePack); +} + +BOOLEAN +NTAPI +VerifyEventWaitable(IN HANDLE Handle, + OUT PVOID *WaitObject, + OUT PVOID *ActualWaitObject) +{ + PVOID Object; + NTSTATUS Status; + POBJECT_TYPE ObjectType; + + /* Reference the object */ + Status = ObReferenceObjectByHandle(Handle, + EVENT_ALL_ACCESS, + NULL, + KernelMode, + &Object, + NULL); + *WaitObject = Object; + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC VerifyEventWaitable: Unable to reference event object (%lx)\n", Status); + return FALSE; + } + + /* Check if the object itself is NOT being used */ + ObjectType = OBJECT_TO_OBJECT_HEADER(Object)->Type; + if (ObjectType->TypeInfo.UseDefaultObject == FALSE) + { + /* Get the actual object that's being used for the wait */ + *ActualWaitObject = (PVOID)((ULONG_PTR)Object + + (ULONG_PTR)ObjectType->DefaultObject); + return TRUE; + } + + /* Drop the reference we took */ + SAC_DBG(SAC_DBG_INIT, "SAC VerifyEventWaitable: event object not waitable!\n"); + ObDereferenceObject(*WaitObject); + return FALSE; +} + +NTSTATUS +NTAPI +SerialBufferGetChar(OUT PCHAR Char) +{ + /* Check if nothing's been produced yet */ + if (SerialPortConsumerIndex == SerialPortProducerIndex) + { + return STATUS_NO_DATA_DETECTED; + } + + /* Consume the produced character and clear it*/ + *Char = SerialPortBuffer[SerialPortConsumerIndex]; + SerialPortBuffer[SerialPortConsumerIndex] = ANSI_NULL; + + /* Advance the index and return success */ + _InterlockedExchange(&SerialPortConsumerIndex, + (SerialPortConsumerIndex + 1) & + (SAC_SERIAL_PORT_BUFFER_SIZE - 1)); + return STATUS_SUCCESS; +} ULONG ConvertAnsiToUnicode( @@ -32,24 +773,6 @@ IsCmdEventRegistrationProcess( return FALSE; } -VOID -InitializeCmdEventInfo( - VOID - ) -{ - -} - -BOOLEAN -VerifyEventWaitable( - IN PVOID Object, - OUT PVOID *WaitObject, - OUT PVOID *ActualWaitObject - ) -{ - return FALSE; -} - NTSTATUS InvokeUserModeService( VOID @@ -58,32 +781,6 @@ InvokeUserModeService( return STATUS_NOT_IMPLEMENTED; } -VOID -SacFormatMessage( - IN PWCHAR FormattedString, - IN PWCHAR MessageString, - IN ULONG MessageSize - ) -{ - -} - -NTSTATUS -TearDownGlobalMessageTable( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -PWCHAR -GetMessage( - IN ULONG MessageIndex - ) -{ - return NULL; -} - BOOLEAN SacTranslateUtf8ToUnicode( IN CHAR Utf8Char, @@ -94,50 +791,6 @@ SacTranslateUtf8ToUnicode( return FALSE; } -BOOLEAN -SacTranslateUnicodeToUtf8( - IN PWCHAR SourceBuffer, - IN ULONG SourceBufferLength, - OUT PCHAR DestinationBuffer, - IN ULONG DestinationBufferSize, - IN ULONG UTF8Count, - OUT PULONG ProcessedCount - ) -{ - return FALSE; -} - -NTSTATUS -GetRegistryValueBuffer( - IN PCWSTR KeyName, - IN PWCHAR ValueName, - IN PKEY_VALUE_PARTIAL_INFORMATION ValueBuffer - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -SetRegistryValue( - IN PCWSTR KeyName, - IN PWCHAR ValueName, - IN ULONG Type, - IN PVOID Data, - IN ULONG DataSize - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -CopyRegistryValueData( - IN PVOID Dest, - IN PKEY_VALUE_PARTIAL_INFORMATION ValueBuffer - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS TranslateMachineInformationText( IN PWCHAR Buffer) @@ -145,55 +798,6 @@ TranslateMachineInformationText( return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -TranslateMachineInformationXML( - IN PWCHAR Buffer, - IN PWCHAR ExtraData - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RegisterBlueScreenMachineInformation( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -VOID -FreeMachineInformation( - VOID - ) -{ - -} - -NTSTATUS -SerialBufferGetChar( - OUT PCHAR Char - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -GetCommandConsoleLaunchingPermission( - OUT PBOOLEAN Permission - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ImposeSacCmdServiceStartTypePolicy( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS CopyAndInsertStringAtInterval( IN PWCHAR SourceStr, @@ -229,11 +833,3 @@ UnregisterSacCmdEvent( { return STATUS_NOT_IMPLEMENTED; } - -NTSTATUS -UTF8EncodeAndSend( - IN PWCHAR String - ) -{ - return STATUS_NOT_IMPLEMENTED; -} diff --git a/reactos/include/reactos/mc/CMakeLists.txt b/reactos/include/reactos/mc/CMakeLists.txt index 1e62d5fe576..8037a7c2575 100644 --- a/reactos/include/reactos/mc/CMakeLists.txt +++ b/reactos/include/reactos/mc/CMakeLists.txt @@ -7,7 +7,8 @@ list(APPEND UNICODE_SOURCE neteventmsg.mc ntiologc.mc ntstatus.mc - pciclass.mc) + pciclass.mc + sacmsg.mc) add_message_headers(ANSI ${ANSI_SOURCE}) # FIXME: this needs testing before switching to unicode diff --git a/reactos/include/reactos/mc/sacmsg.mc b/reactos/include/reactos/mc/sacmsg.mc index dce4a07f41f..4d3052c3d42 100644 --- a/reactos/include/reactos/mc/sacmsg.mc +++ b/reactos/include/reactos/mc/sacmsg.mc @@ -1,17 +1,17 @@ MessageId=1 -SymbolicName=SACDRV_1 +SymbolicName=SAC_INIT_STATUS Language=English Computer is booting, SAC started and initialized.\n\nUse the \"ch -?\" command for information about using channels.\nUse the \"?\" command for general help. . MessageId=2 -SymbolicName=SACDRV_2 +SymbolicName=SAC_NEWLINE Language=English . MessageId=3 -SymbolicName=SACDRV_3 +SymbolicName=SAC_PROMPT Language=English SAC>%0 . @@ -59,9 +59,9 @@ Paging is now OFF. . MessageId=11 -SymbolicName=SACDRV_11 +SymbolicName=SAC_OUT_OF_MEMORY_PROMPT Language=English -Paging is now OFF. +THIS LOOKS LIKE A BUG??? . MessageId=12 @@ -173,7 +173,7 @@ lock Lock access to Command Prompt channels. . MessageId=48 -SymbolicName=SACDRV_48 +SymbolicName=SAC_FAIL_PROMPT Language=English Failed with status 0x%%X. . @@ -269,13 +269,13 @@ SAC cannot raise the process priority any higher. . MessageId=65 -SymbolicName=SACDRV_65 +SymbolicName=SAC_SHUTDOWN_FAIL_PROMPT Language=English SAC failed to shutdown the system. . MessageId=66 -SymbolicName=SACDRV_66 +SymbolicName=SAC_RESTART_FAIL_PROMPT Language=English SAC failed to restart the system. . @@ -551,19 +551,19 @@ ch Channel management commands. Use ch -? for more help. . MessageId=113 -SymbolicName=SACDRV_113 +SymbolicName=SAC_RESTART_TIME_PROMPT Language=English Time since last reboot: %%d:%%02d:%%02d . MessageId=114 -SymbolicName=SACDRV_114 +SymbolicName=SAC_RESTART_PROMPT Language=English SAC preparing to restart the system. . MessageId=115 -SymbolicName=SACDRV_115 +SymbolicName=SAC_SHUTDOWN_PROMPT Language=English SAC preparing to shutdown the system. . @@ -641,13 +641,13 @@ Error: There is no channel present at the specified index. . MessageId=144 -SymbolicName=SACDRV_144 +SymbolicName=SAC_CHANNEL_NAME Language=English SAC%0 . MessageId=145 -SymbolicName=SACDRV_145 +SymbolicName=SAC_CHANNEL_DESCRIPTION Language=English Special Administration Console%0 . From be917e611863f2708aba97c6ed1bf644444f2e1c Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 6 Aug 2013 01:14:34 +0000 Subject: [PATCH 13/25] [SACDRV]: Set dependency on sacmsg. svn path=/trunk/; revision=59650 --- reactos/drivers/sac/driver/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/drivers/sac/driver/CMakeLists.txt b/reactos/drivers/sac/driver/CMakeLists.txt index 187402740c5..1a28f98b485 100644 --- a/reactos/drivers/sac/driver/CMakeLists.txt +++ b/reactos/drivers/sac/driver/CMakeLists.txt @@ -16,4 +16,5 @@ list(APPEND SOURCE add_library(sacdrv SHARED ${SOURCE} sacdrv.rc) set_module_type(sacdrv kernelmodedriver) add_importlibs(sacdrv ntoskrnl hal) +add_dependencies(sacdrv sacmsg) add_cd_file(TARGET sacdrv DESTINATION reactos/system32/drivers NO_CAB FOR all) From 4ae0d21a9ce95e9e2cd514a10c962fd81ac2f2b4 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 6 Aug 2013 01:25:27 +0000 Subject: [PATCH 14/25] [SACDRV]: Great job GCC at not realizing a variable was not initialized. svn path=/trunk/; revision=59651 --- reactos/drivers/sac/driver/util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/drivers/sac/driver/util.c b/reactos/drivers/sac/driver/util.c index f536915e23f..32daaac3bc3 100644 --- a/reactos/drivers/sac/driver/util.c +++ b/reactos/drivers/sac/driver/util.c @@ -133,6 +133,7 @@ PreloadGlobalMessageTable(IN PVOID ImageBase) if (GlobalMessageTable) goto Exit; /* Loop through up to 200 messages */ + TotalLength = 0; for (MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) { /* Find this message ID in the string table*/ From 002291ac9392e493f73d15ff00b7aa6edd09b302 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 6 Aug 2013 01:38:13 +0000 Subject: [PATCH 15/25] [SACDRV]: Another attempt to make MSVC happy. svn path=/trunk/; revision=59652 --- reactos/drivers/sac/driver/chanmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/drivers/sac/driver/chanmgr.c b/reactos/drivers/sac/driver/chanmgr.c index bf65042a3ee..a005a1e98c8 100644 --- a/reactos/drivers/sac/driver/chanmgr.c +++ b/reactos/drivers/sac/driver/chanmgr.c @@ -396,7 +396,7 @@ ChanMgrCreateChannel(OUT PSAC_CHANNEL *Channel, { /* Free slot found, attempt to use it */ ASSERT(!CHANNEL_SLOT_IS_IN_USE(i)); - _InterlockedCompareExchangePointer((void* volatile*)&ChannelArray[i], NewChannel, NULL); + _InterlockedCompareExchange((PLONG)&ChannelArray[i], (LONG)NewChannel, 0); if (ChannelArray[i] == NewChannel) break; } } From 8a3e88a0f267bb4337af860b9f877e8821fb56c6 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 6 Aug 2013 01:42:43 +0000 Subject: [PATCH 16/25] [NDK]: Update DNF_NEED_TO_ENUM to DNF_LEGACY_RESOURCE_DEVICENODE. The former wasn't used and doesn't seem to exist, the latter is the actual real flag with that value. [NTOSKRNL]: Commit an old patch of mine that sets up the right frontend code in IoAssignResources. All it does is add some error checking before calling the old halfplemented backend. svn path=/trunk/; revision=59653 --- reactos/include/ndk/iotypes.h | 2 +- reactos/ntoskrnl/io/iomgr/iorsrce.c | 83 +++++++++++++++++++++++------ reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 2 - 3 files changed, 67 insertions(+), 20 deletions(-) diff --git a/reactos/include/ndk/iotypes.h b/reactos/include/ndk/iotypes.h index 32e634946bc..0cc4e6dab34 100644 --- a/reactos/include/ndk/iotypes.h +++ b/reactos/include/ndk/iotypes.h @@ -174,7 +174,7 @@ extern POBJECT_TYPE NTSYSAPI IoDriverObjectType; #define DNF_LEGACY_DRIVER 0x00004000 #define DNF_STOPPED 0x00008000 #define DNF_WILL_BE_REMOVED 0x00010000 -#define DNF_NEED_TO_ENUM 0x00020000 +#define DNF_LEGACY_RESOURCE_DEVICENODE 0x00020000 #define DNF_NOT_CONFIGURED 0x00040000 #define DNF_REINSTALL 0x00080000 #define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00100000 // ??? diff --git a/reactos/ntoskrnl/io/iomgr/iorsrce.c b/reactos/ntoskrnl/io/iomgr/iorsrce.c index febd24b5b3d..a498d6d40fb 100644 --- a/reactos/ntoskrnl/io/iomgr/iorsrce.c +++ b/reactos/ntoskrnl/io/iomgr/iorsrce.c @@ -908,37 +908,86 @@ IoReportResourceUsage(PUNICODE_STRING DriverClassName, return STATUS_SUCCESS; } -/* - * @halfplemented - */ -NTSTATUS NTAPI -IoAssignResources(PUNICODE_STRING RegistryPath, - PUNICODE_STRING DriverClassName, - PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT DeviceObject, - PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, - PCM_RESOURCE_LIST* AllocatedResources) +NTSTATUS +NTAPI +IopLegacyResourceAllocation(IN ARBITER_REQUEST_SOURCE AllocationType, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) { NTSTATUS Status; - - DPRINT1("IoAssignResources is halfplemented!\n"); - *AllocatedResources = NULL; - Status = IopFixupResourceListWithRequirements(RequestedResources, + DPRINT1("IopLegacyResourceAllocation is halfplemented!\n"); + + Status = IopFixupResourceListWithRequirements(ResourceRequirements, AllocatedResources); if (!NT_SUCCESS(Status)) { if (Status == STATUS_CONFLICTING_ADDRESSES) + { DPRINT1("Denying an attempt to claim resources currently in use by another device!\n"); - + } + return Status; } - + /* TODO: Claim resources in registry */ - return STATUS_SUCCESS; } +/* + * @implemented + */ +NTSTATUS +NTAPI +IoAssignResources(IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, + IN OUT PCM_RESOURCE_LIST* AllocatedResources) +{ + PDEVICE_NODE DeviceNode; + + /* Do we have a DO? */ + if (DeviceObject) + { + /* Get its device node */ + DeviceNode = IopGetDeviceNode(DeviceObject); + if ((DeviceNode) && !(DeviceNode->Flags & DNF_LEGACY_RESOURCE_DEVICENODE)) + { + /* New drivers should not call this API */ + KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, + 0, + 0, + (ULONG_PTR)DeviceObject, + (ULONG_PTR)DriverObject); + } + } + + /* Did the driver supply resources? */ + if (RequestedResources) + { + /* Make sure there's actually something useful in them */ + if (!(RequestedResources->AlternativeLists) || !(RequestedResources->List[0].Count)) + { + /* Empty resources are no resources */ + RequestedResources = NULL; + } + } + + /* Initialize output if given */ + if (AllocatedResources) *AllocatedResources = NULL; + + /* Call internal helper function */ + return IopLegacyResourceAllocation(ArbiterRequestLegacyAssigned, + DriverObject, + DeviceObject, + RequestedResources, + AllocatedResources); +} + /* * FUNCTION: * Reads and returns Hardware information from the appropriate hardware registry key. diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 3aca4ce583b..44fa2ea0973 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -2268,8 +2268,6 @@ IopEnumerateDevice( &DeviceNode->InstancePath); } - DeviceNode->Flags &= ~DNF_NEED_TO_ENUM; - DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); Stack.Parameters.QueryDeviceRelations.Type = BusRelations; From c88b1f0a7d5899b42300cb8e00377c52cdddb87c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 6 Aug 2013 10:40:36 +0000 Subject: [PATCH 17/25] [KERNEL32] Clarify a comment; fix a parameter given to BasepIsRealtimeAllowed. svn path=/trunk/; revision=59654 --- reactos/dll/win32/kernel32/client/proc.c | 34 +++++++++++++----------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index 384a4e1bcae..e72273a45f6 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -2270,17 +2270,17 @@ C_ASSERT(PROCESS_PRIORITY_CLASS_REALTIME == (PROCESS_PRIORITY_CLASS_HIGH + 1)); BOOL WINAPI CreateProcessInternalW(IN HANDLE hUserToken, - IN LPCWSTR lpApplicationName, - IN LPWSTR lpCommandLine, - IN LPSECURITY_ATTRIBUTES lpProcessAttributes, - IN LPSECURITY_ATTRIBUTES lpThreadAttributes, - IN BOOL bInheritHandles, - IN DWORD dwCreationFlags, - IN LPVOID lpEnvironment, - IN LPCWSTR lpCurrentDirectory, - IN LPSTARTUPINFOW lpStartupInfo, - IN LPPROCESS_INFORMATION lpProcessInformation, - OUT PHANDLE hNewToken) + IN LPCWSTR lpApplicationName, + IN LPWSTR lpCommandLine, + IN LPSECURITY_ATTRIBUTES lpProcessAttributes, + IN LPSECURITY_ATTRIBUTES lpThreadAttributes, + IN BOOL bInheritHandles, + IN DWORD dwCreationFlags, + IN LPVOID lpEnvironment, + IN LPCWSTR lpCurrentDirectory, + IN LPSTARTUPINFOW lpStartupInfo, + IN LPPROCESS_INFORMATION lpProcessInformation, + OUT PHANDLE hNewToken) { // // Core variables used for creating the initial process and thread @@ -2503,7 +2503,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, else if (dwCreationFlags & REALTIME_PRIORITY_CLASS) { PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; - PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(0) != NULL); + PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(FALSE) != NULL); } else { @@ -3003,7 +3003,7 @@ StartScan: if ((dwCreationFlags & CREATE_FORCEDOS) && (BaseStaticServerData->IsWowTaskReady)) { - /* This request can't be satisifeed, instead, a separate VDM is needed */ + /* This request can't be satisfied, instead, a separate VDM is needed */ dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM); dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; @@ -4263,7 +4263,11 @@ StartScan: if ((ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI) || (IsWowApp)) { - /* Some flag sent to CSRSS, not sure for what purpose */ + /* + * For GUI apps we turn on the 2nd bit. This allow CSRSS server dlls + * (basesrv in particular) to know whether or not this is a GUI or a + * TUI application. + */ AddToHandle(CreateProcessMsg->ProcessHandle, 2); /* Also check if the parent is also a GUI process */ @@ -4271,7 +4275,7 @@ StartScan: if ((NtHeaders) && (NtHeaders->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)) { - /* Let it know that it should dislay the hourglass mouse cursor */ + /* Let it know that it should display the hourglass mouse cursor */ AddToHandle(CreateProcessMsg->ProcessHandle, 1); } } From 72738923954c9a07a3fcf6b94fd68850236be18b Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 6 Aug 2013 13:48:36 +0000 Subject: [PATCH 18/25] [PSDK] * Annotate wincrypt.h. svn path=/trunk/; revision=59655 --- reactos/include/psdk/wincrypt.h | 2714 ++++++++++++++++++++++++------- 1 file changed, 2087 insertions(+), 627 deletions(-) diff --git a/reactos/include/psdk/wincrypt.h b/reactos/include/psdk/wincrypt.h index d6850a75d99..e66b3770da4 100644 --- a/reactos/include/psdk/wincrypt.h +++ b/reactos/include/psdk/wincrypt.h @@ -1096,20 +1096,33 @@ typedef struct _CERT_SYSTEM_STORE_RELOCATE_PARA { } DUMMYUNIONNAME2; } CERT_SYSTEM_STORE_RELOCATE_PARA, *PCERT_SYSTEM_STORE_RELOCATE_PARA; -typedef BOOL (WINAPI *PFN_CERT_ENUM_SYSTEM_STORE_LOCATION)( - LPCWSTR pwszStoreLocation, DWORD dwFlags, void *pvReserved, void *pvArg); +typedef BOOL +(WINAPI *PFN_CERT_ENUM_SYSTEM_STORE_LOCATION)( + _In_ LPCWSTR pwszStoreLocation, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Inout_opt_ void *pvArg); -typedef BOOL (WINAPI *PFN_CERT_ENUM_SYSTEM_STORE)(const void *pvSystemStore, - DWORD dwFlags, PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, - void *pvArg); +typedef BOOL +(WINAPI *PFN_CERT_ENUM_SYSTEM_STORE)( + _In_ const void *pvSystemStore, + _In_ DWORD dwFlags, + _In_ PCERT_SYSTEM_STORE_INFO pStoreInfo, + _Reserved_ void *pvReserved, + _Inout_opt_ void *pvArg); -typedef BOOL (WINAPI *PFN_CERT_ENUM_PHYSICAL_STORE)(const void *pvSystemStore, - DWORD dwFlags, LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, - void *pvReserved, void *pvArg); +typedef BOOL +(WINAPI *PFN_CERT_ENUM_PHYSICAL_STORE)( + _In_ const void *pvSystemStore, + _In_ DWORD dwFlags, + _In_ LPCWSTR pwszStoreName, + _In_ PCERT_PHYSICAL_STORE_INFO pStoreInfo, + _Reserved_ void *pvReserved, + _Inout_opt_ void *pvArg); /* Encode/decode object */ -typedef LPVOID (__WINE_ALLOC_SIZE(1) WINAPI *PFN_CRYPT_ALLOC)(size_t cbsize); -typedef VOID (WINAPI *PFN_CRYPT_FREE)(LPVOID pv); +typedef LPVOID (__WINE_ALLOC_SIZE(1) WINAPI *PFN_CRYPT_ALLOC)(_In_ size_t cbsize); +typedef VOID(WINAPI *PFN_CRYPT_FREE)(_In_ LPVOID pv); typedef struct _CRYPT_ENCODE_PARA { DWORD cbSize; @@ -1132,58 +1145,114 @@ typedef struct _CERT_STORE_PROV_INFO { HCRYPTOIDFUNCADDR hStoreProvFuncAddr2; } CERT_STORE_PROV_INFO, *PCERT_STORE_PROV_INFO; -typedef BOOL (WINAPI *PFN_CERT_DLL_OPEN_STORE_PROV_FUNC)( - LPCSTR lpszStoreProvider, DWORD dwEncodingType, HCRYPTPROV_LEGACY hCryptProv, - DWORD dwFlags, const void *pvPara, HCERTSTORE hCertStore, - PCERT_STORE_PROV_INFO pStoreProvInfo); +typedef BOOL +(WINAPI *PFN_CERT_DLL_OPEN_STORE_PROV_FUNC)( + _In_ LPCSTR lpszStoreProvider, + _In_ DWORD dwEncodingType, + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwFlags, + _In_opt_ const void *pvPara, + _In_ HCERTSTORE hCertStore, + _Inout_ PCERT_STORE_PROV_INFO pStoreProvInfo); -typedef void (WINAPI *PFN_CERT_STORE_PROV_CLOSE)(HCERTSTOREPROV hStoreProv, - DWORD dwFlags); +typedef void +(WINAPI *PFN_CERT_STORE_PROV_CLOSE)( + _Inout_opt_ HCERTSTOREPROV hStoreProv, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_READ_CERT)(HCERTSTOREPROV hStoreProv, - PCCERT_CONTEXT pStoreCertContext, DWORD dwFlags, - PCCERT_CONTEXT *ppProvCertContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_READ_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pStoreCertContext, + _In_ DWORD dwFlags, + _Outptr_ PCCERT_CONTEXT *ppProvCertContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_WRITE_CERT)(HCERTSTOREPROV hStoreProv, - PCCERT_CONTEXT pCertContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_WRITE_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_DELETE_CERT)( - HCERTSTOREPROV hStoreProv, PCCERT_CONTEXT pCertContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_DELETE_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_SET_CERT_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCERT_CONTEXT pCertContext, DWORD dwPropId, - DWORD dwFlags, const void *pvData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_SET_CERT_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_READ_CRL)(HCERTSTOREPROV hStoreProv, - PCCRL_CONTEXT pStoreCrlContext, DWORD dwFlags, - PCCRL_CONTEXT *ppProvCrlContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_READ_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pStoreCrlContext, + _In_ DWORD dwFlags, + _Outptr_ PCCRL_CONTEXT *ppProvCrlContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_WRITE_CRL)(HCERTSTOREPROV hStoreProv, - PCCRL_CONTEXT pCrlContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_WRITE_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_DELETE_CRL)(HCERTSTOREPROV hStoreProv, - PCCRL_CONTEXT pCrlContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_DELETE_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_SET_CRL_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCRL_CONTEXT pCrlContext, DWORD dwPropId, - DWORD dwFlags, const void *pvData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_SET_CRL_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_READ_CTL)(HCERTSTOREPROV hStoreProv, - PCCTL_CONTEXT pStoreCtlContext, DWORD dwFlags, - PCCTL_CONTEXT *ppProvCtlContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_READ_CTL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pStoreCtlContext, + _In_ DWORD dwFlags, + _Outptr_ PCCTL_CONTEXT *ppProvCtlContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_WRITE_CTL)(HCERTSTOREPROV hStoreProv, - PCCTL_CONTEXT pCtlContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_WRITE_CTL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_DELETE_CTL)( - HCERTSTOREPROV hStoreProv, PCCTL_CONTEXT pCtlContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_DELETE_CTL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_SET_CTL_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCTL_CONTEXT pCtlContext, DWORD dwPropId, - DWORD dwFlags, const void *pvData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_SET_CTL_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_CONTROL)(HCERTSTOREPROV hStoreProv, - DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_CONTROL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ DWORD dwFlags, + _In_ DWORD dwCtrlType, + _In_opt_ void const *pvCtrlPara); typedef struct _CERT_STORE_PROV_FIND_INFO { DWORD cbSize; @@ -1195,36 +1264,79 @@ typedef struct _CERT_STORE_PROV_FIND_INFO { typedef const CERT_STORE_PROV_FIND_INFO CCERT_STORE_PROV_FIND_INFO, *PCCERT_STORE_PROV_FIND_INFO; -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FIND_CERT)(HCERTSTOREPROV hStoreProv, - PCCERT_STORE_PROV_FIND_INFO pFindInfo, PCCERT_CONTEXT pPrevCertContext, - DWORD dwFlags, void **ppvStoreProvFindInfo, PCCERT_CONTEXT *ppProvCertContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_FIND_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_STORE_PROV_FIND_INFO pFindInfo, + _In_ PCCERT_CONTEXT pPrevCertContext, + _In_ DWORD dwFlags, + _Inout_ void **ppvStoreProvFindInfo, + _Outptr_ PCCERT_CONTEXT *ppProvCertContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CERT)( - HCERTSTOREPROV hStoreProv, PCCERT_CONTEXT pCertContext, - void *pvStoreProvFindInfo, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ void *pvStoreProvFindInfo, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_GET_CERT_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCERT_CONTEXT pCertContext, DWORD dwPropId, - DWORD dwFlags, void *pvData, DWORD *pcbData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_GET_CERT_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FIND_CRL)(HCERTSTOREPROV hStoreProv, - PCCERT_STORE_PROV_FIND_INFO pFindInfo, PCCRL_CONTEXT pPrevCrlContext, - DWORD dwFlags, void **ppvStoreProvFindInfo, PCCRL_CONTEXT *ppProvCrlContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_FIND_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_STORE_PROV_FIND_INFO pFindInfo, + _In_ PCCRL_CONTEXT pPrevCrlContext, + _In_ DWORD dwFlags, + _Inout_ void **ppvStoreProvFindInfo, + _Outptr_ PCCRL_CONTEXT *ppProvCrlContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CRL)( - HCERTSTOREPROV hStoreProv, PCCRL_CONTEXT pCrlContext, - void *pvStoreProvFindInfo, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ void *pvStoreProvFindInfo, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_GET_CRL_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCRL_CONTEXT pCrlContext, DWORD dwPropId, - DWORD dwFlags, void *pvData, DWORD *pcbData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_GET_CRL_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FIND_CTL)(HCERTSTOREPROV hStoreProv, - PCCTL_CONTEXT pCtlContext, void *pvStoreProvFindInfo, DWORD dwFlags); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_FIND_CTL)( + _In_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_STORE_PROV_FIND_INFO pFindInfo, + _In_ PCCTL_CONTEXT pPrevCtlContext, + _In_ DWORD dwFlags, + _Inout_ void **ppvStoreProvFindInfo, + _Outptr_ PCCTL_CONTEXT *ppProvCtlContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_GET_CTL_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCTL_CONTEXT pCtlContext, DWORD dwPropId, - DWORD dwFlags, void *pvData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_GET_CTL_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); typedef struct _CERT_CREATE_CONTEXT_PARA { DWORD cbSize; @@ -1237,10 +1349,17 @@ typedef struct _CRYPT_OID_FUNC_ENTRY { void *pvFuncAddr; } CRYPT_OID_FUNC_ENTRY, *PCRYPT_OID_FUNC_ENTRY; -typedef BOOL (WINAPI *PFN_CRYPT_ENUM_OID_FUNC)(DWORD dwEncodingType, - LPCSTR pszFuncName, LPCSTR pszOID, DWORD cValue, const DWORD rgdwValueType[], - LPCWSTR const rgpwszValueName[], const BYTE * const rgpbValueData[], - const DWORD rgcbValueData[], void *pvArg); +typedef BOOL +(WINAPI *PFN_CRYPT_ENUM_OID_FUNC)( + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszFuncName, + _In_ LPCSTR pszOID, + _In_ DWORD cValue, + _In_reads_(cValue) const DWORD rgdwValueType[], + _In_reads_(cValue) LPCWSTR const rgpwszValueName[], + _In_reads_(cValue) const BYTE * const rgpbValueData[], + _In_reads_(cValue) const DWORD rgcbValueData[], + _Inout_opt_ void *pvArg); #define CRYPT_MATCH_ANY_ENCODING_TYPE 0xffffffff @@ -1258,8 +1377,10 @@ typedef struct _CRYPT_OID_INFO { } CRYPT_OID_INFO, *PCRYPT_OID_INFO; typedef const CRYPT_OID_INFO CCRYPT_OID_INFO, *PCCRYPT_OID_INFO; -typedef BOOL (WINAPI *PFN_CRYPT_ENUM_OID_INFO)(PCCRYPT_OID_INFO pInfo, - void *pvArg); +typedef BOOL +(WINAPI *PFN_CRYPT_ENUM_OID_INFO)( + _In_ PCCRYPT_OID_INFO pInfo, + _Inout_opt_ void *pvArg); typedef struct _CRYPT_SIGN_MESSAGE_PARA { DWORD cbSize; @@ -1288,8 +1409,12 @@ typedef struct _CRYPT_SIGN_MESSAGE_PARA { #define CRYPT_MESSAGE_KEYID_SIGNER_FLAG 0x00000004 #define CRYPT_MESSAGE_SILENT_KEYSET_FLAG 0x00000008 -typedef PCCERT_CONTEXT (WINAPI *PFN_CRYPT_GET_SIGNER_CERTIFICATE)(void *pvArg, - DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hMsgCertStore); +typedef PCCERT_CONTEXT +(WINAPI *PFN_CRYPT_GET_SIGNER_CERTIFICATE)( + _Inout_opt_ void *pvGetArg, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pSignerId, + _In_ HCERTSTORE hMsgCertStore); typedef struct _CRYPT_VERIFY_MESSAGE_PARA { DWORD cbSize; @@ -1373,24 +1498,30 @@ typedef struct _CRYPT_URL_INFO { typedef HANDLE HCRYPTASYNC, *PHCRYPTASYNC; -typedef void (WINAPI *PFN_CRYPT_ASYNC_PARAM_FREE_FUNC)(LPSTR pszParamOid, - LPVOID pvParam); +typedef void +(WINAPI *PFN_CRYPT_ASYNC_PARAM_FREE_FUNC)( + _In_ LPSTR pszParamOid, + _In_ LPVOID pvParam); #define CRYPT_PARAM_ASYNC_RETRIEVAL_COMPLETION ((LPCSTR)1) #define CRYPT_PARAM_CANCEL_ASYNC_RETRIEVAL ((LPCSTR)2) -typedef void (WINAPI *PFN_CRYPT_ASYNC_RETRIEVAL_COMPLETION_FUNC)( - void *pvCompletion, DWORD dwCompletionCode, LPCSTR pszURL, LPSTR pszObjectOid, - void *pvObject); +typedef void +(WINAPI *PFN_CRYPT_ASYNC_RETRIEVAL_COMPLETION_FUNC)( + _Inout_opt_ void *pvCompletion, + _In_ DWORD dwCompletionCode, + _In_ LPCSTR pszURL, + _In_opt_ LPSTR pszObjectOid, + _In_ void *pvObject); -typedef struct _CRYPT_ASYNC_RETRIEVAL_COMPLETION -{ - PFN_CRYPT_ASYNC_RETRIEVAL_COMPLETION_FUNC pfnCompletion; - void *pvCompletion; +typedef struct _CRYPT_ASYNC_RETRIEVAL_COMPLETION { + __callback PFN_CRYPT_ASYNC_RETRIEVAL_COMPLETION_FUNC pfnCompletion; + _Inout_opt_ void *pvCompletion; } CRYPT_ASYNC_RETRIEVAL_COMPLETION, *PCRYPT_ASYNC_RETRIEVAL_COMPLETION; -typedef BOOL (WINAPI *PFN_CANCEL_ASYNC_RETRIEVAL_FUNC)( - HCRYPTASYNC hAsyncRetrieve); +typedef BOOL +(WINAPI *PFN_CANCEL_ASYNC_RETRIEVAL_FUNC)( + _In_opt_ HCRYPTASYNC hAsyncRetrieve); typedef struct _CRYPT_BLOB_ARRAY { @@ -1429,8 +1560,11 @@ typedef struct _CRYPT_RETRIEVE_AUX_INFO { DWORD dwMaxUrlRetrievalByteCount; } CRYPT_RETRIEVE_AUX_INFO, *PCRYPT_RETRIEVE_AUX_INFO; -typedef void (WINAPI *PFN_FREE_ENCODED_OBJECT_FUNC)(LPCSTR pszObjectOid, - PCRYPT_BLOB_ARRAY pObject, void *pvFreeContext); +typedef void +(WINAPI *PFN_FREE_ENCODED_OBJECT_FUNC)( + _In_opt_ LPCSTR pszObjectOid, + _Inout_ PCRYPT_BLOB_ARRAY pObject, + _Inout_opt_ void *pvFreeContext); #define SCHEME_OID_RETRIEVE_ENCODED_OBJECT_FUNC \ "SchemeDllRetrieveEncodedObject" @@ -1478,7 +1612,10 @@ BOOL WINAPI ContextDllCreateObjectContext(LPCSTR pszObjectOid, #define CRYPT_CHECK_FRESHNESS_TIME_VALIDITY 0x00000400 #define CRYPT_ACCUMULATIVE_TIMEOUT 0x00000800 -typedef BOOL (WINAPI *PFN_CRYPT_CANCEL_RETRIEVAL)(DWORD dwFlags, void *pvArg); +typedef BOOL +(WINAPI *PFN_CRYPT_CANCEL_RETRIEVAL)( + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg); typedef struct _CERT_CRL_CONTEXT_PAIR { @@ -3405,8 +3542,12 @@ typedef struct _CERT_CHAIN_ENGINE_CONFIG /* message-related definitions */ -typedef BOOL (WINAPI *PFN_CMSG_STREAM_OUTPUT)(const void *pvArg, BYTE *pbData, - DWORD cbData, BOOL fFinal); +typedef BOOL +(WINAPI *PFN_CMSG_STREAM_OUTPUT)( + _In_opt_ const void *pvArg, + _In_reads_bytes_opt_(cbData) BYTE *pbData, + _In_ DWORD cbData, + _In_ BOOL fFinal); #define CMSG_INDEFINITE_LENGTH 0xffffffff @@ -3808,8 +3949,8 @@ typedef struct _CMSG_CMS_RECIPIENT_INFO { #define CMSG_KEY_AGREE_VERSION CMSG_ENVELOPED_RECIPIENT_V3 #define CMSG_MAIL_LIST_VERSION CMSG_ENVELOPED_RECIPIENT_V4 -typedef void * (WINAPI *PFN_CMSG_ALLOC)(size_t cb); -typedef void (WINAPI *PFN_CMSG_FREE)(void *pv); +typedef void * (WINAPI *PFN_CMSG_ALLOC)(_In_ size_t cb); +typedef void (WINAPI *PFN_CMSG_FREE)(_Inout_ void *pv); typedef struct _CMSG_CONTENT_ENCRYPT_INFO { DWORD cbSize; @@ -3841,20 +3982,27 @@ typedef struct _CMSG_CTRL_KEY_TRANS_DECRYPT_PARA { DWORD dwRecipientIndex; } CMSG_CTRL_KEY_TRANS_DECRYPT_PARA, *PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA; -typedef BOOL (WINAPI *PFN_CMSG_GEN_CONTENT_ENCRYPT_KEY)( - PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, DWORD dwFlags, - void *pvReserved); +typedef BOOL +(WINAPI *PFN_CMSG_GEN_CONTENT_ENCRYPT_KEY)( + _Inout_ PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); -typedef BOOL (WINAPI *PFN_CMSG_EXPORT_KEY_TRANS)( - PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, - PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO pKeyTransEncodeInfo, - PCMSG_KEY_TRANS_ENCRYPT_INFO pKeyTransEncryptInfo, - DWORD dwFlags, void *pvReserved); +typedef BOOL +(WINAPI *PFN_CMSG_EXPORT_KEY_TRANS)( + _In_ PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, + _In_ PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO pKeyTransEncodeInfo, + _Inout_ PCMSG_KEY_TRANS_ENCRYPT_INFO pKeyTransEncryptInfo, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); -typedef BOOL (WINAPI *PFN_CMSG_IMPORT_KEY_TRANS)( - PCRYPT_ALGORITHM_IDENTIFIER pContentEncryptionAlgorithm, - PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA pKeyTransDecryptPara, DWORD dwFlags, - void *pvReserved, HCRYPTKEY *phContentEncryptKey); +typedef BOOL +(WINAPI *PFN_CMSG_IMPORT_KEY_TRANS)( + _In_ PCRYPT_ALGORITHM_IDENTIFIER pContentEncryptionAlgorithm, + _In_ PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA pKeyTransDecryptPara, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Out_ HCRYPTKEY *phContentEncryptKey); /* CryptMsgGetAndVerifySigner flags */ #define CMSG_TRUSTED_SIGNER_FLAG 0x1 @@ -3879,489 +4027,1476 @@ typedef BOOL (WINAPI *PFN_CMSG_IMPORT_KEY_TRANS)( /* function declarations */ /* advapi32.dll */ -WINADVAPI BOOL WINAPI CryptAcquireContextA(HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD); -WINADVAPI BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD); -#define CryptAcquireContext WINELIB_NAME_AW(CryptAcquireContext) -WINADVAPI BOOL WINAPI CryptGenRandom (HCRYPTPROV, DWORD, BYTE *); -WINADVAPI BOOL WINAPI CryptContextAddRef (HCRYPTPROV, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptCreateHash (HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH *); -WINADVAPI BOOL WINAPI CryptDecrypt (HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE *, DWORD *); -WINADVAPI BOOL WINAPI CryptDeriveKey (HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY *); -WINADVAPI BOOL WINAPI CryptDestroyHash (HCRYPTHASH); -WINADVAPI BOOL WINAPI CryptDestroyKey (HCRYPTKEY); -WINADVAPI BOOL WINAPI CryptDuplicateKey (HCRYPTKEY, DWORD *, DWORD, HCRYPTKEY *); -WINADVAPI BOOL WINAPI CryptDuplicateHash (HCRYPTHASH, DWORD *, DWORD, HCRYPTHASH *); -WINADVAPI BOOL WINAPI CryptEncrypt (HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE *, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptEnumProvidersA (DWORD, DWORD *, DWORD, DWORD *, LPSTR, DWORD *); -WINADVAPI BOOL WINAPI CryptEnumProvidersW (DWORD, DWORD *, DWORD, DWORD *, LPWSTR, DWORD *); -#define CryptEnumProviders WINELIB_NAME_AW(CryptEnumProviders) -WINADVAPI BOOL WINAPI CryptEnumProviderTypesA (DWORD, DWORD *, DWORD, DWORD *, LPSTR, DWORD *); -WINADVAPI BOOL WINAPI CryptEnumProviderTypesW (DWORD, DWORD *, DWORD, DWORD *, LPWSTR, DWORD *); -#define CryptEnumProviderTypes WINELIB_NAME_AW(CryptEnumProviderTypes) -WINADVAPI BOOL WINAPI CryptExportKey (HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, BYTE *, DWORD *); -WINADVAPI BOOL WINAPI CryptGenKey (HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY *); -WINADVAPI BOOL WINAPI CryptGetKeyParam (HCRYPTKEY, DWORD, BYTE *, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptGetHashParam (HCRYPTHASH, DWORD, BYTE *, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptGetProvParam (HCRYPTPROV, DWORD, BYTE *, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptGetDefaultProviderA (DWORD, DWORD *, DWORD, LPSTR, DWORD *); -WINADVAPI BOOL WINAPI CryptGetDefaultProviderW (DWORD, DWORD *, DWORD, LPWSTR, DWORD *); -#define CryptGetDefaultProvider WINELIB_NAME_AW(CryptGetDefaultProvider) -WINADVAPI BOOL WINAPI CryptGetUserKey (HCRYPTPROV, DWORD, HCRYPTKEY *); -WINADVAPI BOOL WINAPI CryptHashData (HCRYPTHASH, CONST BYTE *, DWORD, DWORD); -WINADVAPI BOOL WINAPI CryptHashSessionKey (HCRYPTHASH, HCRYPTKEY, DWORD); -WINADVAPI BOOL WINAPI CryptImportKey (HCRYPTPROV, CONST BYTE *, DWORD, HCRYPTKEY, DWORD, HCRYPTKEY *); +WINADVAPI +BOOL +WINAPI +CryptAcquireContextA( + _Out_ HCRYPTPROV *, + _In_opt_ LPCSTR, + _In_opt_ LPCSTR, + _In_ DWORD, + _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptAcquireContextW( + _Out_ HCRYPTPROV *, + _In_opt_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ DWORD, + _In_ DWORD); + +#define CryptAcquireContext WINELIB_NAME_AW(CryptAcquireContext) + +WINADVAPI +BOOL +WINAPI +CryptGenRandom( + _In_ HCRYPTPROV hProv, + _In_ DWORD dwLen, + _Inout_updates_bytes_(dwLen) BYTE *pbBuffer); + +WINADVAPI +BOOL +WINAPI +CryptContextAddRef( + _In_ HCRYPTPROV, + _Reserved_ DWORD *, + _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptCreateHash( + _In_ HCRYPTPROV, + _In_ ALG_ID, + _In_ HCRYPTKEY, + _In_ DWORD, + _Out_ HCRYPTHASH *); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptDecrypt( + _In_ HCRYPTKEY hKey, + _In_ HCRYPTHASH hHash, + _In_ BOOL Final, + _In_ DWORD dwFlags, + _Inout_updates_bytes_to_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen); + +WINADVAPI +BOOL +WINAPI +CryptDeriveKey( + _In_ HCRYPTPROV, + _In_ ALG_ID, + _In_ HCRYPTHASH, + _In_ DWORD, + _Out_ HCRYPTKEY *); + +WINADVAPI BOOL WINAPI CryptDestroyHash(_In_ HCRYPTHASH); +WINADVAPI BOOL WINAPI CryptDestroyKey(_In_ HCRYPTKEY); + +WINADVAPI +BOOL +WINAPI +CryptDuplicateKey( + _In_ HCRYPTKEY, + _Reserved_ DWORD *, + _In_ DWORD, + _Out_ HCRYPTKEY *); + +WINADVAPI +BOOL +WINAPI +CryptDuplicateHash( + _In_ HCRYPTHASH, + _Reserved_ DWORD *, + _In_ DWORD, + _Out_ HCRYPTHASH *); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEncrypt( + _In_ HCRYPTKEY hKey, + _In_ HCRYPTHASH hHash, + _In_ BOOL Final, + _In_ DWORD dwFlags, + _Inout_updates_bytes_to_opt_(dwBufLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen, + _In_ DWORD dwBufLen); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEnumProvidersA( + _In_ DWORD dwIndex, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_ DWORD *pdwProvType, + _Out_writes_bytes_to_opt_(*pcbProvName, *pcbProvName) LPSTR szProvName, + _Inout_ DWORD *pcbProvName); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEnumProvidersW( + _In_ DWORD dwIndex, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_ DWORD *pdwProvType, + _Out_writes_bytes_to_opt_(*pcbProvName, *pcbProvName) LPWSTR szProvName, + _Inout_ DWORD *pcbProvName); + +#define CryptEnumProviders WINELIB_NAME_AW(CryptEnumProviders) + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEnumProviderTypesA( + _In_ DWORD dwIndex, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_ DWORD *pdwProvType, + _Out_writes_bytes_to_opt_(*pcbTypeName, *pcbTypeName) LPSTR szTypeName, + _Inout_ DWORD *pcbTypeName); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEnumProviderTypesW( + _In_ DWORD dwIndex, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_ DWORD *pdwProvType, + _Out_writes_bytes_to_opt_(*pcbTypeName, *pcbTypeName) LPWSTR szTypeName, + _Inout_ DWORD *pcbTypeName); + +#define CryptEnumProviderTypes WINELIB_NAME_AW(CryptEnumProviderTypes) + +WINADVAPI +BOOL +WINAPI +CryptExportKey( + _In_ HCRYPTKEY hKey, + _In_ HCRYPTKEY hExpKey, + _In_ DWORD dwBlobType, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen); + +WINADVAPI +BOOL +WINAPI +CryptGenKey( + _In_ HCRYPTPROV, + _In_ ALG_ID, + _In_ DWORD, + _Out_ HCRYPTKEY *); + +WINADVAPI +BOOL +WINAPI +CryptGetKeyParam( + _In_ HCRYPTKEY hKey, + _In_ DWORD dwParam, + _Out_writes_bytes_to_opt_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen, + _In_ DWORD dwFlags); + +WINADVAPI +BOOL +WINAPI +CryptGetHashParam( + _In_ HCRYPTHASH hHash, + _In_ DWORD dwParam, + _Out_writes_bytes_to_opt_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen, + _In_ DWORD dwFlags); + +WINADVAPI +BOOL +WINAPI +CryptGetProvParam( + _In_ HCRYPTPROV hProv, + _In_ DWORD dwParam, + _Out_writes_bytes_to_opt_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen, + _In_ DWORD dwFlags); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptGetDefaultProviderA( + _In_ DWORD dwProvType, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbProvName, *pcbProvName) LPSTR pszProvName, + _Inout_ DWORD *pcbProvName); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptGetDefaultProviderW( + _In_ DWORD dwProvType, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbProvName, *pcbProvName) LPWSTR pszProvName, + _Inout_ DWORD *pcbProvName); + +#define CryptGetDefaultProvider WINELIB_NAME_AW(CryptGetDefaultProvider) + +WINADVAPI BOOL WINAPI CryptGetUserKey(_In_ HCRYPTPROV, _In_ DWORD, _Out_ HCRYPTKEY *); + +WINADVAPI +BOOL +WINAPI +CryptHashData( + _In_ HCRYPTHASH hHash, + _In_reads_bytes_(dwDataLen) CONST BYTE *pbData, + _In_ DWORD dwDataLen, + _In_ DWORD dwFlags); + +WINADVAPI BOOL WINAPI CryptHashSessionKey(_In_ HCRYPTHASH, _In_ HCRYPTKEY, _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptImportKey( + _In_ HCRYPTPROV hProv, + _In_reads_bytes_(dwDataLen) CONST BYTE *pbData, + _In_ DWORD dwDataLen, + _In_ HCRYPTKEY hPubKey, + _In_ DWORD dwFlags, + _Out_ HCRYPTKEY *phKey); + #if (NTDDI_VERSION >= NTDDI_WINXP) -WINADVAPI BOOL WINAPI CryptReleaseContext (HCRYPTPROV, DWORD); +WINADVAPI BOOL WINAPI CryptReleaseContext(_In_ HCRYPTPROV, _In_ DWORD); #else -WINADVAPI BOOL WINAPI CryptReleaseContext (HCRYPTPROV, ULONG_PTR); +WINADVAPI BOOL WINAPI CryptReleaseContext(_In_ HCRYPTPROV, _In_ ULONG_PTR); #endif -WINADVAPI BOOL WINAPI CryptSetHashParam (HCRYPTHASH, DWORD, CONST BYTE *, DWORD); -WINADVAPI BOOL WINAPI CryptSetKeyParam (HCRYPTKEY, DWORD, CONST BYTE *, DWORD); -WINADVAPI BOOL WINAPI CryptSetProviderA (LPCSTR, DWORD); -WINADVAPI BOOL WINAPI CryptSetProviderW (LPCWSTR, DWORD); -#define CryptSetProvider WINELIB_NAME_AW(CryptSetProvider) -WINADVAPI BOOL WINAPI CryptSetProviderExA (LPCSTR, DWORD, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptSetProviderExW (LPCWSTR, DWORD, DWORD *, DWORD); -#define CryptSetProviderEx WINELIB_NAME_AW(CryptSetProviderEx) -WINADVAPI BOOL WINAPI CryptSetProvParam (HCRYPTPROV, DWORD, CONST BYTE *, DWORD); -WINADVAPI BOOL WINAPI CryptSignHashA (HCRYPTHASH, DWORD, LPCSTR, DWORD, BYTE *, DWORD *); -WINADVAPI BOOL WINAPI CryptSignHashW (HCRYPTHASH, DWORD, LPCWSTR, DWORD, BYTE *, DWORD *); -#define CryptSignHash WINELIB_NAME_AW(CryptSignHash) -WINADVAPI BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH, CONST BYTE *, DWORD, HCRYPTKEY, LPCSTR, DWORD); -WINADVAPI BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH, CONST BYTE *, DWORD, HCRYPTKEY, LPCWSTR, DWORD); -#define CryptVerifySignature WINELIB_NAME_AW(CryptVerifySignature) + +WINADVAPI +BOOL +WINAPI +CryptSetHashParam( + _In_ HCRYPTHASH, + _In_ DWORD, + _In_ CONST BYTE *, + _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptSetKeyParam( + _In_ HCRYPTKEY, + _In_ DWORD, + _In_ CONST BYTE *, + _In_ DWORD); + +WINADVAPI BOOL WINAPI CryptSetProviderA(_In_ LPCSTR, _In_ DWORD); +WINADVAPI BOOL WINAPI CryptSetProviderW(_In_ LPCWSTR, _In_ DWORD); + +#define CryptSetProvider WINELIB_NAME_AW(CryptSetProvider) + +WINADVAPI +BOOL +WINAPI +CryptSetProviderExA( + _In_ LPCSTR, + _In_ DWORD, + _Reserved_ DWORD *, + _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptSetProviderExW( + _In_ LPCWSTR, + _In_ DWORD, + _Reserved_ DWORD *, + _In_ DWORD); + +#define CryptSetProviderEx WINELIB_NAME_AW(CryptSetProviderEx) + +WINADVAPI BOOL WINAPI CryptSetProvParam(_In_ HCRYPTPROV, _In_ DWORD, _In_ CONST BYTE *, _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptSignHashA( + _In_ HCRYPTHASH hHash, + _In_ DWORD dwKeySpec, + _In_opt_ LPCSTR szDescription, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pdwSigLen, *pdwSigLen) BYTE *pbSignature, + _Inout_ DWORD *pdwSigLen); + +WINADVAPI +BOOL +WINAPI +CryptSignHashW( + _In_ HCRYPTHASH hHash, + _In_ DWORD dwKeySpec, + _In_opt_ LPCWSTR szDescription, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pdwSigLen, *pdwSigLen) BYTE *pbSignature, + _Inout_ DWORD *pdwSigLen); + +#define CryptSignHash WINELIB_NAME_AW(CryptSignHash) + +WINADVAPI +BOOL +WINAPI +CryptVerifySignatureA( + _In_ HCRYPTHASH hHash, + _In_reads_bytes_(dwSigLen) CONST BYTE *pbSignature, + _In_ DWORD dwSigLen, + _In_ HCRYPTKEY hPubKey, + _In_opt_ LPCSTR szDescription, + _In_ DWORD dwFlags); + +WINADVAPI +BOOL +WINAPI +CryptVerifySignatureW( + _In_ HCRYPTHASH hHash, + _In_reads_bytes_(dwSigLen) CONST BYTE *pbSignature, + _In_ DWORD dwSigLen, + _In_ HCRYPTKEY hPubKey, + _In_opt_ LPCWSTR szDescription, + _In_ DWORD dwFlags); + +#define CryptVerifySignature WINELIB_NAME_AW(CryptVerifySignature) /* crypt32.dll functions */ -LPVOID WINAPI CryptMemAlloc(ULONG cbSize) __WINE_ALLOC_SIZE(1); -LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize) __WINE_ALLOC_SIZE(2); -VOID WINAPI CryptMemFree(LPVOID pv); +LPVOID WINAPI CryptMemAlloc(_In_ ULONG cbSize) __WINE_ALLOC_SIZE(1); +LPVOID WINAPI CryptMemRealloc(_In_opt_ LPVOID pv, _In_ ULONG cbSize) __WINE_ALLOC_SIZE(2); +VOID WINAPI CryptMemFree(_In_opt_ LPVOID pv); + +_Success_(return != 0) +BOOL +WINAPI +CryptBinaryToStringA( + _In_reads_bytes_(cbBinary) const BYTE *pbBinary, + _In_ DWORD cbBinary, + _In_ DWORD dwFlags, + _Out_writes_to_opt_(*pcchString, *pcchString) LPSTR pszString, + _Inout_ DWORD *pcchString); + +_Success_(return != 0) +BOOL +WINAPI +CryptBinaryToStringW( + _In_reads_bytes_(cbBinary) const BYTE *pbBinary, + _In_ DWORD cbBinary, + _In_ DWORD dwFlags, + _Out_writes_to_opt_(*pcchString, *pcchString) LPWSTR pszString, + _Inout_ DWORD *pcchString); -BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, - DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString); -BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary, - DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString); #define CryptBinaryToString WINELIB_NAME_AW(CryptBinaryToString) -BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, - DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, - DWORD *pdwSkip, DWORD *pdwFlags); -BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString, - DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, - DWORD *pdwSkip, DWORD *pdwFlags); +BOOL +WINAPI +CryptStringToBinaryA( + _In_reads_(cchString) LPCSTR pszString, + _In_ DWORD cchString, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbBinary, *pcbBinary) BYTE *pbBinary, + _Inout_ DWORD *pcbBinary, + _Out_opt_ DWORD *pdwSkip, + _Out_opt_ DWORD *pdwFlags); + +BOOL +WINAPI +CryptStringToBinaryW( + _In_reads_(cchString) LPCWSTR pszString, + _In_ DWORD cchString, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbBinary, *pcbBinary) BYTE *pbBinary, + _Inout_ DWORD *pcbBinary, + _Out_opt_ DWORD *pdwSkip, + _Out_opt_ DWORD *pdwFlags); + #define CryptStringToBinary WINELIB_NAME_AW(CryptStringToBinary) -BOOL WINAPI CryptCreateAsyncHandle(DWORD dwFlags, PHCRYPTASYNC phAsync); -BOOL WINAPI CryptSetAsyncParam(HCRYPTASYNC hAsync, LPSTR pszParamOid, - LPVOID pvParam, PFN_CRYPT_ASYNC_PARAM_FREE_FUNC pfnFree); -BOOL WINAPI CryptGetAsyncParam(HCRYPTASYNC hAsync, LPSTR pszParamOid, - LPVOID *ppvParam, PFN_CRYPT_ASYNC_PARAM_FREE_FUNC *ppfnFree); -BOOL WINAPI CryptCloseAsyncHandle(HCRYPTASYNC hAsync); +BOOL +WINAPI +CryptCreateAsyncHandle( + _In_ DWORD dwFlags, + _Out_ PHCRYPTASYNC phAsync); -BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD,LPCSTR,DWORD,LPCWSTR); -BOOL WINAPI CryptRegisterOIDFunction(DWORD,LPCSTR,LPCSTR,LPCWSTR,LPCSTR); -BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, LPCWSTR szValueName, DWORD *pdwValueType, - BYTE *pbValueData, DWORD *pcbValueData); -BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType, - const BYTE *pbValueData, DWORD cbValueData); -BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD,LPCSTR,LPCWSTR); -BOOL WINAPI CryptUnregisterOIDFunction(DWORD,LPCSTR,LPCSTR); -BOOL WINAPI CryptEnumOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, DWORD dwFlags, void *pvArg, - PFN_CRYPT_ENUM_OID_FUNC pfnEnumOIDFunc); -HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR,DWORD); -BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, - DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList); -BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, - DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr, - HCRYPTOIDFUNCADDR *phFuncAddr); -BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, - DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr, - HCRYPTOIDFUNCADDR *phFuncAddr); -BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, - DWORD dwFlags); -BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, - DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry, - const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags); -BOOL WINAPI CryptInstallDefaultContext(HCRYPTPROV hCryptProv, - DWORD dwDefaultType, const void *pvDefaultPara, DWORD dwFlags, - void *pvReserved, HCRYPTDEFAULTCONTEXT *phDefaultContext); -BOOL WINAPI CryptUninstallDefaultContext(HCRYPTDEFAULTCONTEXT hDefaultContext, - DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptSetAsyncParam( + _In_ HCRYPTASYNC hAsync, + _In_ LPSTR pszParamOid, + _In_opt_ LPVOID pvParam, + __callback PFN_CRYPT_ASYNC_PARAM_FREE_FUNC pfnFree); -BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg, - PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo); -PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, - DWORD dwGroupId); -BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO pInfo, DWORD dwFlags); -BOOL WINAPI CryptUnregisterOIDInfo(PCCRYPT_OID_INFO pInfo); +BOOL +WINAPI +CryptGetAsyncParam( + _In_ HCRYPTASYNC hAsync, + _In_ LPSTR pszParamOid, + _Outptr_opt_result_maybenull_ LPVOID* ppvParam, + _Outptr_opt_result_maybenull_ __callback PFN_CRYPT_ASYNC_PARAM_FREE_FUNC* ppfnFree); -LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName); +BOOL +WINAPI +CryptRegisterDefaultOIDFunction( + _In_ DWORD, + _In_ LPCSTR, + _In_ DWORD, + _In_ LPCWSTR); -LPCSTR WINAPI CertAlgIdToOID(DWORD dwAlgId); -DWORD WINAPI CertOIDToAlgId(LPCSTR pszObjId); +BOOL +WINAPI +CryptRegisterOIDFunction( + _In_ DWORD, + _In_ LPCSTR, + _In_ LPCSTR, + _In_opt_ LPCWSTR, + _In_opt_ LPCSTR); + +BOOL +WINAPI +CryptGetOIDFunctionValue( + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszFuncName, + _In_ LPCSTR pszOID, + _In_opt_ LPCWSTR pwszValueName, + _Out_opt_ DWORD *pdwValueType, + _Out_writes_bytes_to_opt_(*pcbValueData, *pcbValueData) BYTE *pbValueData, + _Inout_opt_ DWORD *pcbValueData); + +BOOL +WINAPI +CryptSetOIDFunctionValue( + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszFuncName, + _In_ LPCSTR pszOID, + _In_opt_ LPCWSTR pwszValueName, + _In_ DWORD dwValueType, + _In_reads_bytes_opt_(cbValueData) const BYTE *pbValueData, + _In_ DWORD cbValueData); + +BOOL WINAPI CryptUnregisterDefaultOIDFunction(_In_ DWORD, _In_ LPCSTR, _In_ LPCWSTR); +BOOL WINAPI CryptUnregisterOIDFunction(_In_ DWORD, _In_ LPCSTR, _In_ LPCSTR); + +BOOL +WINAPI +CryptEnumOIDFunction( + _In_ DWORD dwEncodingType, + _In_opt_ LPCSTR pszFuncName, + _In_opt_ LPCSTR pszOID, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CRYPT_ENUM_OID_FUNC pfnEnumOIDFunc); + +HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(_In_ LPCSTR, _In_ DWORD); + +_Success_(return != 0) +BOOL +WINAPI +CryptGetDefaultOIDDllList( + _In_ HCRYPTOIDFUNCSET hFuncSet, + _In_ DWORD dwEncodingType, + _Out_writes_to_opt_(*pcchDllList, *pcchDllList) _Post_ _NullNull_terminated_ WCHAR *pwszDllList, + _Inout_ DWORD *pcchDllList); + +_Success_(return != 0) +BOOL +WINAPI +CryptGetDefaultOIDFunctionAddress( + _In_ HCRYPTOIDFUNCSET hFuncSet, + _In_ DWORD dwEncodingType, + _In_opt_ LPCWSTR pwszDll, + _In_ DWORD dwFlags, + _Outptr_ void **ppvFuncAddr, + _Inout_ HCRYPTOIDFUNCADDR *phFuncAddr); + +_Success_(return != 0) +BOOL +WINAPI +CryptGetOIDFunctionAddress( + _In_ HCRYPTOIDFUNCSET hFuncSet, + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszOID, + _In_ DWORD dwFlags, + _Outptr_ void **ppvFuncAddr, + _Out_ HCRYPTOIDFUNCADDR *phFuncAddr); + +BOOL +WINAPI +CryptFreeOIDFunctionAddress( + _In_ HCRYPTOIDFUNCADDR hFuncAddr, + _In_ DWORD dwFlags); + +BOOL +WINAPI +CryptInstallOIDFunctionAddress( + _In_opt_ HMODULE hModule, + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszFuncName, + _In_ DWORD cFuncEntry, + _In_reads_(cFuncEntry) const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], + _In_ DWORD dwFlags); + +BOOL +WINAPI +CryptInstallDefaultContext( + _In_ HCRYPTPROV hCryptProv, + _In_ DWORD dwDefaultType, + _In_opt_ const void *pvDefaultPara, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Out_ HCRYPTDEFAULTCONTEXT *phDefaultContext); + +BOOL +WINAPI +CryptUninstallDefaultContext( + _In_opt_ HCRYPTDEFAULTCONTEXT hDefaultContext, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); + +BOOL +WINAPI +CryptEnumOIDInfo( + _In_ DWORD dwGroupId, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo); + +PCCRYPT_OID_INFO +WINAPI +CryptFindOIDInfo( + _In_ DWORD dwKeyType, + _In_ void *pvKey, + _In_ DWORD dwGroupId); + +BOOL WINAPI CryptRegisterOIDInfo(_In_ PCCRYPT_OID_INFO pInfo, _In_ DWORD dwFlags); +BOOL WINAPI CryptUnregisterOIDInfo(_In_ PCCRYPT_OID_INFO pInfo); + +LPCWSTR WINAPI CryptFindLocalizedName(_In_ LPCWSTR pwszCryptName); + +LPCSTR WINAPI CertAlgIdToOID(_In_ DWORD dwAlgId); +DWORD WINAPI CertOIDToAlgId(_In_ LPCSTR pszObjId); /* cert store functions */ -HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwEncodingType, - HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const void *pvPara); +_Must_inspect_result_ +HCERTSTORE +WINAPI +CertOpenStore( + _In_ LPCSTR lpszStoreProvider, + _In_ DWORD dwEncodingType, + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwFlags, + _In_opt_ const void *pvPara); + +HCERTSTORE +WINAPI +CertOpenSystemStoreA( + _In_opt_ HCRYPTPROV_LEGACY hProv, + _In_ LPCSTR szSubsystemProtocol); + +HCERTSTORE +WINAPI +CertOpenSystemStoreW( + _In_opt_ HCRYPTPROV_LEGACY hProv, + _In_ LPCWSTR szSubSystemProtocol); -HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, - LPCSTR szSubSystemProtocol); -HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, - LPCWSTR szSubSystemProtocol); #define CertOpenSystemStore WINELIB_NAME_AW(CertOpenSystemStore) -PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pPrev); +PCCERT_CONTEXT +WINAPI +CertEnumCertificatesInStore( + _In_ HCERTSTORE hCertStore, + _In_opt_ PCCERT_CONTEXT pPrev); -PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, - PCCRL_CONTEXT pPrev); +PCCRL_CONTEXT +WINAPI +CertEnumCRLsInStore( + _In_ HCERTSTORE hCertStore, + _In_opt_ PCCRL_CONTEXT pPrevCrlContext); -PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore, - PCCTL_CONTEXT pPrev); +PCCTL_CONTEXT +WINAPI +CertEnumCTLsInStore( + _In_ HCERTSTORE hCertStore, + _In_opt_ PCCTL_CONTEXT pPrevCtlContext); -BOOL WINAPI CertEnumSystemStoreLocation(DWORD dwFlags, void *pvArg, - PFN_CERT_ENUM_SYSTEM_STORE_LOCATION pfnEnum); +BOOL +WINAPI +CertEnumSystemStoreLocation( + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CERT_ENUM_SYSTEM_STORE_LOCATION pfnEnum); -BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara, - void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum); +BOOL +WINAPI +CertEnumSystemStore( + _In_ DWORD dwFlags, + _In_opt_ void *pvSystemStoreLocationPara, + _Inout_opt_ void *pvArg, + __callback PFN_CERT_ENUM_SYSTEM_STORE pfnEnum); -BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags, - void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum); +BOOL +WINAPI +CertEnumPhysicalStore( + _In_ const void *pvSystemStore, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum); -BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, - LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, void *pvReserved); +BOOL +WINAPI +CertRegisterPhysicalStore( + _In_ const void *pvSystemStore, + _In_ DWORD dwFlags, + _In_ LPCWSTR pwszStoreName, + _In_ PCERT_PHYSICAL_STORE_INFO pStoreInfo, + _Reserved_ void *pvReserved); -BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, - DWORD dwSaveAs, DWORD dwSaveTo, void* pvSaveToPara, DWORD dwFlags); +BOOL +WINAPI +CertSaveStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwEncodingType, + _In_ DWORD dwSaveAs, + _In_ DWORD dwSaveTo, + _Inout_ void *pvSaveToPara, + _In_ DWORD dwFlags); -BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, - HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority); +BOOL +WINAPI +CertAddStoreToCollection( + _In_ HCERTSTORE hCollectionStore, + _In_opt_ HCERTSTORE hSiblingStore, + _In_ DWORD dwUpdateFlags, + _In_ DWORD dwPriority); -void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore, - HCERTSTORE hSiblingStore); +void +WINAPI +CertRemoveStoreFromCollection( + _In_ HCERTSTORE hCollectionStore, + _In_ HCERTSTORE hSiblingStore); -BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, - HCERTCHAINENGINE *phChainEngine); +_Success_(return != 0) +BOOL +WINAPI +CertCreateCertificateChainEngine( + _In_ PCERT_CHAIN_ENGINE_CONFIG pConfig, + _Out_ HCERTCHAINENGINE *phChainEngine); -BOOL WINAPI CertResyncCertificateChainEngine(HCERTCHAINENGINE hChainEngine); +BOOL WINAPI CertResyncCertificateChainEngine(_In_opt_ HCERTCHAINENGINE hChainEngine); -VOID WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine); +VOID WINAPI CertFreeCertificateChainEngine(_In_opt_ HCERTCHAINENGINE hChainEngine); -BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, - PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, - PCERT_CHAIN_PARA pChainPara, DWORD dwFlags, LPVOID pvReserved, - PCCERT_CHAIN_CONTEXT *ppChainContext); +_Success_(return != 0) +BOOL +WINAPI +CertGetCertificateChain( + _In_opt_ HCERTCHAINENGINE hChainEngine, + _In_ PCCERT_CONTEXT pCertContext, + _In_opt_ LPFILETIME pTime, + _In_opt_ HCERTSTORE hAdditionalStore, + _In_ PCERT_CHAIN_PARA pChainPara, + _In_ DWORD dwFlags, + _Reserved_ LPVOID pvReserved, + _Out_ PCCERT_CHAIN_CONTEXT* ppChainContext); -PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain( - PCCERT_CHAIN_CONTEXT pChainContext); +PCCERT_CHAIN_CONTEXT +WINAPI +CertDuplicateCertificateChain( + _In_ PCCERT_CHAIN_CONTEXT pChainContext); -VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext); +VOID WINAPI CertFreeCertificateChain(_In_ PCCERT_CHAIN_CONTEXT pChainContext); -PCCERT_CHAIN_CONTEXT WINAPI CertFindChainInStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, - const void *pvFindPara, PCCERT_CHAIN_CONTEXT pPrevChainContext); +PCCERT_CHAIN_CONTEXT +WINAPI +CertFindChainInStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFindFlags, + _In_ DWORD dwFindType, + _In_opt_ const void *pvFindPara, + _In_opt_ PCCERT_CHAIN_CONTEXT pPrevChainContext); -BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, - PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, - PCERT_CHAIN_POLICY_STATUS pPolicyStatus); +BOOL +WINAPI +CertVerifyCertificateChainPolicy( + _In_ LPCSTR pszPolicyOID, + _In_ PCCERT_CHAIN_CONTEXT pChainContext, + _In_ PCERT_CHAIN_POLICY_PARA pPolicyPara, + _Inout_ PCERT_CHAIN_POLICY_STATUS pPolicyStatus); -DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext, - DWORD dwPropId); +DWORD +WINAPI +CertEnumCertificateContextProperties( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId); -BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, - DWORD dwPropId, void *pvData, DWORD *pcbData); +BOOL +WINAPI +CertGetCertificateContextProperty( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, - DWORD dwPropId, DWORD dwFlags, const void *pvData); +BOOL +WINAPI +CertSetCertificateContextProperty( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext, - DWORD dwPropId); +DWORD +WINAPI +CertEnumCRLContextProperties( + _In_ PCCRL_CONTEXT pCRLContext, + _In_ DWORD dwPropId); -BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext, - DWORD dwPropId, void *pvData, DWORD *pcbData); +BOOL +WINAPI +CertGetCRLContextProperty( + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwPropId, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext, - DWORD dwPropId, DWORD dwFlags, const void *pvData); +BOOL +WINAPI +CertSetCRLContextProperty( + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext, - DWORD dwPropId); +DWORD +WINAPI +CertEnumCTLContextProperties( + _In_ PCCTL_CONTEXT pCTLContext, + _In_ DWORD dwPropId); -BOOL WINAPI CertEnumSubjectInSortedCTL(PCCTL_CONTEXT pCTLContext, - void **ppvNextSubject, PCRYPT_DER_BLOB pSubjectIdentifier, - PCRYPT_DER_BLOB pEncodedAttributes); +BOOL +WINAPI +CertEnumSubjectInSortedCTL( + _In_ PCCTL_CONTEXT pCtlContext, + _Inout_ void **ppvNextSubject, + _Out_opt_ PCRYPT_DER_BLOB pSubjectIdentifier, + _Out_opt_ PCRYPT_DER_BLOB pEncodedAttributes); -BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext, - DWORD dwPropId, void *pvData, DWORD *pcbData); +BOOL +WINAPI +CertGetCTLContextProperty( + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwPropId, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext, - DWORD dwPropId, DWORD dwFlags, const void *pvData); +BOOL +WINAPI +CertSetCTLContextProperty( + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, - void *pvData, DWORD *pcbData); +_Success_(return != 0) +BOOL +WINAPI +CertGetStoreProperty( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwPropId, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, - DWORD dwFlags, const void *pvData); +BOOL +WINAPI +CertSetStoreProperty( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags, - DWORD dwCtrlType, void const *pvCtrlPara); +BOOL +WINAPI +CertControlStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwFlags, + _In_ DWORD dwCtrlType, + _In_opt_ void const *pvCtrlPara); -HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore); +HCERTSTORE WINAPI CertDuplicateStore(_In_ HCERTSTORE hCertStore); -BOOL WINAPI CertCloseStore( HCERTSTORE hCertStore, DWORD dwFlags ); +BOOL WINAPI CertCloseStore(_In_opt_ HCERTSTORE hCertStore, _In_ DWORD dwFlags); -BOOL WINAPI CertFreeCertificateContext( PCCERT_CONTEXT pCertContext ); +BOOL WINAPI CertFreeCertificateContext(_In_opt_ PCCERT_CONTEXT pCertContext); -BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext ); +BOOL WINAPI CertFreeCRLContext(_In_opt_ PCCRL_CONTEXT pCrlContext); -BOOL WINAPI CertFreeCTLContext( PCCTL_CONTEXT pCtlContext ); +BOOL WINAPI CertFreeCTLContext(_In_opt_ PCCTL_CONTEXT pCtlContext); -BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, - PCCERT_CONTEXT *ppStoreContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddCertificateContextToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCERT_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCRLContextToStore( HCERTSTORE hCertStore, - PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition, - PCCRL_CONTEXT *ppStoreContext ); +_Success_(return != 0) +BOOL +WINAPI +CertAddCRLContextToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCRL_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCTLContextToStore( HCERTSTORE hCertStore, - PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition, - PCCTL_CONTEXT *ppStoreContext ); +_Success_(return != 0) +BOOL +WINAPI +CertAddCTLContextToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCTL_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, - PCCERT_CONTEXT *ppStoreContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddCertificateLinkToStore( + _In_ HCERTSTORE hCertStore, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCERT_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCRLLinkToStore(HCERTSTORE hCertStore, - PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition, - PCCRL_CONTEXT *ppStoreContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddCRLLinkToStore( + _In_ HCERTSTORE hCertStore, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCRL_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCTLLinkToStore(HCERTSTORE hCertStore, - PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition, - PCCTL_CONTEXT *ppStoreContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddCTLLinkToStore( + _In_ HCERTSTORE hCertStore, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCTL_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, - DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddEncodedCertificateToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbCertEncoded) const BYTE *pbCertEncoded, + _In_ DWORD cbCertEncoded, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCERT_CONTEXT *ppCertContext); + +BOOL +WINAPI +CertAddEncodedCertificateToSystemStoreA( + _In_ LPCSTR szCertStoreName, + _In_reads_bytes_(cbCertEncoded) const BYTE *pbCertEncoded, + _In_ DWORD cbCertEncoded); + +BOOL +WINAPI +CertAddEncodedCertificateToSystemStoreW( + _In_ LPCWSTR szCertStoreName, + _In_reads_bytes_(cbCertEncoded) const BYTE *pbCertEncoded, + _In_ DWORD cbCertEncoded); -BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName, - const BYTE *pbCertEncoded, DWORD cbCertEncoded); -BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName, - const BYTE *pbCertEncoded, DWORD cbCertEncoded); #define CertAddEncodedCertificateToSystemStore \ WINELIB_NAME_AW(CertAddEncodedCertificateToSystemStore) -BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded, - DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddEncodedCRLToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbCrlEncoded) const BYTE *pbCrlEncoded, + _In_ DWORD cbCrlEncoded, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCRL_CONTEXT *ppCrlContext); -BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore, - DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded, - DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddEncodedCTLToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ DWORD dwMsgAndCertEncodingType, + _In_reads_bytes_(cbCtlEncoded) const BYTE *pbCtlEncoded, + _In_ DWORD cbCtlEncoded, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCTL_CONTEXT *ppCtlContext); -BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore, - const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags, - DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddSerializedElementToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_reads_bytes_(cbElement) const BYTE *pbElement, + _In_ DWORD cbElement, + _In_ DWORD dwAddDisposition, + _In_ DWORD dwFlags, + _In_ DWORD dwContextTypeFlags, + _Out_opt_ DWORD *pdwContextType, + _Outptr_opt_ const void **ppvContext); -BOOL WINAPI CertCompareCertificate(DWORD dwCertEncodingType, - PCERT_INFO pCertId1, PCERT_INFO pCertId2); -BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, - PCERT_NAME_BLOB pCertName1, PCERT_NAME_BLOB pCertName2); -BOOL WINAPI CertCompareIntegerBlob(PCRYPT_INTEGER_BLOB pInt1, - PCRYPT_INTEGER_BLOB pInt2); -BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, - PCERT_PUBLIC_KEY_INFO pPublicKey1, PCERT_PUBLIC_KEY_INFO pPublicKey2); -DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, - PCERT_PUBLIC_KEY_INFO pPublicKey); +BOOL +WINAPI +CertCompareCertificate( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pCertId1, + _In_ PCERT_INFO pCertId2); -const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType, - const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, - PCERT_CREATE_CONTEXT_PARA pCreatePara); +BOOL +WINAPI +CertCompareCertificateName( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_NAME_BLOB pCertName1, + _In_ PCERT_NAME_BLOB pCertName2); -PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, - const BYTE *pbCertEncoded, DWORD cbCertEncoded); +BOOL +WINAPI +CertCompareIntegerBlob( + _In_ PCRYPT_INTEGER_BLOB pInt1, + _In_ PCRYPT_INTEGER_BLOB pInt2); -PCCRL_CONTEXT WINAPI CertCreateCRLContext( DWORD dwCertEncodingType, - const BYTE* pbCrlEncoded, DWORD cbCrlEncoded); +BOOL +WINAPI +CertComparePublicKeyInfo( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pPublicKey1, + _In_ PCERT_PUBLIC_KEY_INFO pPublicKey2); -PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType, - const BYTE *pbCtlEncoded, DWORD cbCtlEncoded); +DWORD +WINAPI +CertGetPublicKeyLength( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pPublicKey); -PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv, - PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD dwFlags, - PCRYPT_KEY_PROV_INFO pKeyProvInfo, - PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime, - PSYSTEMTIME pEndTime, PCERT_EXTENSIONS pExtensions); +const void * +WINAPI +CertCreateContext( + _In_ DWORD dwContextType, + _In_ DWORD dwEncodingType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _In_ DWORD dwFlags, + _In_opt_ PCERT_CREATE_CONTEXT_PARA pCreatePara); -BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext); +PCCERT_CONTEXT +WINAPI +CertCreateCertificateContext( + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbCertEncoded) const BYTE *pbCertEncoded, + _In_ DWORD cbCertEncoded); -BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext); +PCCRL_CONTEXT +WINAPI +CertCreateCRLContext( + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbCrlEncoded) const BYTE *pbCrlEncoded, + _In_ DWORD cbCrlEncoded); -BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext); +PCCTL_CONTEXT +WINAPI +CertCreateCTLContext( + _In_ DWORD dwMsgAndCertEncodingType, + _In_reads_bytes_(cbCtlEncoded) const BYTE *pbCtlEncoded, + _In_ DWORD cbCtlEncoded); -PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext( - PCCERT_CONTEXT pCertContext); +PCCERT_CONTEXT +WINAPI +CertCreateSelfSignCertificate( + _In_opt_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv, + _In_ PCERT_NAME_BLOB pSubjectIssuerBlob, + _In_ DWORD dwFlags, + _In_opt_ PCRYPT_KEY_PROV_INFO pKeyProvInfo, + _In_opt_ PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, + _In_opt_ PSYSTEMTIME pStartTime, + _In_opt_ PSYSTEMTIME pEndTime, + _In_opt_ PCERT_EXTENSIONS pExtensions); -PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext); +BOOL WINAPI CertDeleteCertificateFromStore(_In_ PCCERT_CONTEXT pCertContext); -PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext); +BOOL WINAPI CertDeleteCRLFromStore(_In_ PCCRL_CONTEXT pCrlContext); -PCCERT_CONTEXT WINAPI CertFindCertificateInStore( HCERTSTORE hCertStore, - DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, - const void *pvFindPara, PCCERT_CONTEXT pPrevCertContext ); +BOOL WINAPI CertDeleteCTLFromStore(_In_ PCCTL_CONTEXT pCtlContext); -PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, - const void *pvFindPara, PCCRL_CONTEXT pPrevCrlContext); +PCCERT_CONTEXT +WINAPI +CertDuplicateCertificateContext( + _In_opt_ PCCERT_CONTEXT pCertContext); -PCCTL_CONTEXT WINAPI CertFindCTLInStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, - const void *pvFindPara, PCCTL_CONTEXT pPrevCtlContext); +PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(_In_opt_ PCCRL_CONTEXT pCrlContext); -PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext, - DWORD *pdwFlags); +PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(_In_opt_ PCCTL_CONTEXT pCtlContext); -PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, PCERT_INFO pCertId); +PCCERT_CONTEXT +WINAPI +CertFindCertificateInStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFindFlags, + _In_ DWORD dwFindType, + _In_opt_ const void *pvFindPara, + _In_opt_ PCCERT_CONTEXT pPrevCertContext); -PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pIssuerContext, PCCRL_CONTEXT pPrevCrlContext, DWORD *pdwFlags); +PCCRL_CONTEXT +WINAPI +CertFindCRLInStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFindFlags, + _In_ DWORD dwFindType, + _In_opt_ const void *pvFindPara, + _In_opt_ PCCRL_CONTEXT pPrevCrlContext); -BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext, - DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); +PCCTL_CONTEXT +WINAPI +CertFindCTLInStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwMsgAndCertEncodingType, + _In_ DWORD dwFindFlags, + _In_ DWORD dwFindType, + _In_opt_ const void *pvFindPara, + _In_opt_ PCCTL_CONTEXT pPrevCtlContext); -BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext, - DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); +PCCERT_CONTEXT +WINAPI +CertGetIssuerCertificateFromStore( + _In_ HCERTSTORE hCertStore, + _In_ PCCERT_CONTEXT pSubjectContext, + _In_opt_ PCCERT_CONTEXT pPrevIssuerContext, + _Inout_ DWORD *pdwFlags); -BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext, - DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); +PCCERT_CONTEXT +WINAPI +CertGetSubjectCertificateFromStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pCertId); -BOOL WINAPI CertGetIntendedKeyUsage(DWORD dwCertEncodingType, - PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage); +PCCRL_CONTEXT +WINAPI +CertGetCRLFromStore( + _In_ HCERTSTORE hCertStore, + _In_opt_ PCCERT_CONTEXT pIssuerContext, + _In_opt_ PCCRL_CONTEXT pPrevCrlContext, + _Inout_ DWORD *pdwFlags); -BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags, - PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage); -BOOL WINAPI CertSetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, - PCERT_ENHKEY_USAGE pUsage); -BOOL WINAPI CertAddEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext, - LPCSTR pszUsageIdentifier); -BOOL WINAPI CertRemoveEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext, - LPCSTR pszUsageIdentifier); -BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts, - int *cNumOIDs, LPSTR *rghOIDs, DWORD *pcbOIDs); +BOOL +WINAPI +CertSerializeCertificateStoreElement( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbElement, *pcbElement) BYTE *pbElement, + _Inout_ DWORD *pcbElement); -BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, - const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded); -BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, - const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, - void *pvEncoded, DWORD *pcbEncoded); +BOOL +WINAPI +CertSerializeCRLStoreElement( + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbElement, *pcbElement) BYTE *pbElement, + _Inout_ DWORD *pcbElement); -BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, - const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, - DWORD *pcbStructInfo); -BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, - const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, - PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo); +BOOL +WINAPI +CertSerializeCTLStoreElement( + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbElement, *pcbElement) BYTE *pbElement, + _Inout_ DWORD *pcbElement); -BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType, - DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType, - const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat); +BOOL +WINAPI +CertGetIntendedKeyUsage( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pCertInfo, + _Out_writes_bytes_all_(cbKeyUsage) BYTE *pbKeyUsage, + _In_ DWORD cbKeyUsage); -BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, - DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, - DWORD *pcbComputedHash); +BOOL +WINAPI +CertGetEnhancedKeyUsage( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbUsage, *pcbUsage) PCERT_ENHKEY_USAGE pUsage, + _Inout_ DWORD *pcbUsage); -BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, - DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, - BYTE *pbComputedHash, DWORD *pcbComputedHash); +BOOL +WINAPI +CertSetEnhancedKeyUsage( + _In_ PCCERT_CONTEXT pCertContext, + _In_opt_ PCERT_ENHKEY_USAGE pUsage); -BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, - const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, - DWORD *pcbComputedHash); +BOOL +WINAPI +CertAddEnhancedKeyUsageIdentifier( + _In_ PCCERT_CONTEXT pCertContext, + _In_ LPCSTR pszUsageIdentifier); -BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void* pvObject, - DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags, - DWORD dwFlags, DWORD* pdwMsgAndCertEncodingType, DWORD* pdwContentType, - DWORD* pdwFormatType, HCERTSTORE* phCertStore, HCRYPTMSG* phMsg, - const void** ppvContext); +BOOL +WINAPI +CertRemoveEnhancedKeyUsageIdentifier( + _In_ PCCERT_CONTEXT pCertContext, + _In_ LPCSTR pszUsageIdentifier); -BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, - DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned, - DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, - const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature); +_Success_(return != 0) +BOOL +WINAPI +CertGetValidUsages( + _In_ DWORD cCerts, + _In_reads_(cCerts) PCCERT_CONTEXT *rghCerts, + _Out_ int *cNumOIDs, + _Out_writes_bytes_to_opt_(*pcbOIDs, *pcbOIDs) LPSTR *rghOIDs, + _Inout_ DWORD *pcbOIDs); -BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, - DWORD dwKeySpec, DWORD dwCertEncodingType, LPCSTR lpszStructType, - const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, - const void *pvHashAuxInfo, BYTE *pbEncoded, DWORD *pcbEncoded); +BOOL +WINAPI +CryptEncodeObject( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_ const void *pvStructInfo, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV_LEGACY hCryptProv, - DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, - PCERT_PUBLIC_KEY_INFO pPublicKey); +BOOL +WINAPI +CryptEncodeObjectEx( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_ const void *pvStructInfo, + _In_ DWORD dwFlags, + _In_opt_ PCRYPT_ENCODE_PARA pEncodePara, + _Out_opt_ void *pvEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv, - DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject, - DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptDecodeObject( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbStructInfo, *pcbStructInfo) void *pvStructInfo, + _Inout_ DWORD *pcbStructInfo); -PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr, - CRYPT_ATTRIBUTE rgAttr[]); -PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions, - CERT_EXTENSION rgExtensions[]); -PCERT_RDN_ATTR WINAPI CertFindRDNAttr(LPCSTR pszObjId, PCERT_NAME_INFO pName); +BOOL +WINAPI +CryptDecodeObjectEx( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _In_ DWORD dwFlags, + _In_opt_ PCRYPT_DECODE_PARA pDecodePara, + _Out_opt_ void *pvStructInfo, + _Inout_ DWORD *pcbStructInfo); -BOOL WINAPI CertFindSubjectInSortedCTL(PCRYPT_DATA_BLOB pSubjectIdentifier, - PCCTL_CONTEXT pCtlContext, DWORD dwFlags, void *pvReserved, - PCRYPT_DER_BLOB pEncodedAttributes); +BOOL +WINAPI +CryptFormatObject( + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFormatType, + _In_ DWORD dwFormatStrType, + _In_opt_ void *pFormatStruct, + _In_opt_ LPCSTR lpszStructType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _At_((WCHAR *) pbFormat, _Out_writes_bytes_to_opt_(*pcbFormat, *pcbFormat)) void *pbFormat, + _Inout_ DWORD *pcbFormat); -BOOL WINAPI CertIsRDNAttrsInCertificateName(DWORD dwCertEncodingType, - DWORD dwFlags, PCERT_NAME_BLOB pCertName, PCERT_RDN pRDN); +BOOL +WINAPI +CryptHashCertificate( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ ALG_ID Algid, + _In_ DWORD dwFlags, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_ DWORD *pcbComputedHash); -BOOL WINAPI CertIsValidCRLForCertificate(PCCERT_CONTEXT pCert, - PCCRL_CONTEXT pCrl, DWORD dwFlags, void *pvReserved); -BOOL WINAPI CertFindCertificateInCRL(PCCERT_CONTEXT pCert, - PCCRL_CONTEXT pCrlContext, DWORD dwFlags, void *pvReserved, - PCRL_ENTRY *ppCrlEntry); -BOOL WINAPI CertVerifyCRLRevocation(DWORD dwCertEncodingType, - PCERT_INFO pCertId, DWORD cCrlInfo, PCRL_INFO rgpCrlInfo[]); +BOOL +WINAPI +CryptHashPublicKeyInfo( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ ALG_ID Algid, + _In_ DWORD dwFlags, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pInfo, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_ DWORD *pcbComputedHash); -BOOL WINAPI CertVerifySubjectCertificateContext(PCCERT_CONTEXT pSubject, - PCCERT_CONTEXT pIssuer, DWORD *pdwFlags); +BOOL +WINAPI +CryptHashToBeSigned( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_ DWORD *pcbComputedHash); -LONG WINAPI CertVerifyCRLTimeValidity(LPFILETIME pTimeToVerify, - PCRL_INFO pCrlInfo); -LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify, - PCERT_INFO pCertInfo); -BOOL WINAPI CertVerifyValidityNesting(PCERT_INFO pSubjectInfo, - PCERT_INFO pIssuerInfo); +BOOL +WINAPI +CryptQueryObject( + _In_ DWORD dwObjectType, + _In_ const void *pvObject, + _In_ DWORD dwExpectedContentTypeFlags, + _In_ DWORD dwExpectedFormatTypeFlags, + _In_ DWORD dwFlags, + _Out_opt_ DWORD *pdwMsgAndCertEncodingType, + _Out_opt_ DWORD *pdwContentType, + _Out_opt_ DWORD *pdwFormatType, + _Out_opt_ HCERTSTORE *phCertStore, + _Out_opt_ HCRYPTMSG *phMsg, + _Outptr_opt_result_maybenull_ const void **ppvContext); -BOOL WINAPI CertVerifyCTLUsage(DWORD dwEncodingType, DWORD dwSubjectType, - void *pvSubject, PCTL_USAGE pSubjectUsage, DWORD dwFlags, - PCTL_VERIFY_USAGE_PARA pVerifyUsagePara, - PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus); +BOOL +WINAPI +CryptSignCertificate( + _In_opt_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + _In_opt_ DWORD dwKeySpec, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbEncodedToBeSigned) const BYTE *pbEncodedToBeSigned, + _In_ DWORD cbEncodedToBeSigned, + _In_ PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, + _In_opt_ const void *pvHashAuxInfo, + _Out_writes_bytes_to_opt_(*pcbSignature, *pcbSignature) BYTE *pbSignature, + _Inout_ DWORD *pcbSignature); -BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, - DWORD cContext, PVOID rgpvContext[], DWORD dwFlags, - PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus); +BOOL +WINAPI +CryptSignAndEncodeCertificate( + _In_opt_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + _In_opt_ DWORD dwKeySpec, + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_ const void *pvStructInfo, + _In_ PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, + _In_opt_ const void *pvHashAuxInfo, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptExportPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, - DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo); -BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, - DWORD dwCertEncodingType, LPSTR pszPublicKeyObjId, DWORD dwFlags, - void *pvAuxInfo, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo); -BOOL WINAPI CryptImportPublicKeyInfo(HCRYPTPROV hCryptProv, - DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY *phKey); -BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, - DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg, - DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey); +_Must_inspect_result_ +BOOL +WINAPI +CryptVerifyCertificateSignature( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _In_ PCERT_PUBLIC_KEY_INFO pPublicKey); -BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, - DWORD dwFlags, void *pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProv, DWORD *pdwKeySpec, - BOOL *pfCallerFreeProv); +_Must_inspect_result_ +BOOL +WINAPI +CryptVerifyCertificateSignatureEx( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwSubjectType, + _In_ void *pvSubject, + _In_ DWORD dwIssuerType, + _In_opt_ void *pvIssuer, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvExtra); -BOOL WINAPI CryptFindCertificateKeyProvInfo(PCCERT_CONTEXT pCert, - DWORD dwFlags, void *pvReserved); +PCRYPT_ATTRIBUTE +WINAPI +CertFindAttribute( + _In_ LPCSTR pszObjId, + _In_ DWORD cAttr, + _In_reads_(cAttr) CRYPT_ATTRIBUTE rgAttr[]); + +PCERT_EXTENSION +WINAPI +CertFindExtension( + _In_ LPCSTR pszObjId, + _In_ DWORD cExtensions, + _In_reads_(cExtensions) CERT_EXTENSION rgExtensions[]); + +PCERT_RDN_ATTR +WINAPI +CertFindRDNAttr( + _In_ LPCSTR pszObjId, + _In_ PCERT_NAME_INFO pName); + +BOOL +WINAPI +CertFindSubjectInSortedCTL( + _In_ PCRYPT_DATA_BLOB pSubjectIdentifier, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Out_opt_ PCRYPT_DER_BLOB pEncodedAttributes); + +BOOL +WINAPI +CertIsRDNAttrsInCertificateName( + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFlags, + _In_ PCERT_NAME_BLOB pCertName, + _In_ PCERT_RDN pRDN); + +BOOL +WINAPI +CertIsValidCRLForCertificate( + _In_ PCCERT_CONTEXT pCert, + _In_ PCCRL_CONTEXT pCrl, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); + +BOOL +WINAPI +CertFindCertificateInCRL( + _In_ PCCERT_CONTEXT pCert, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Outptr_result_maybenull_ PCRL_ENTRY *ppCrlEntry); + +BOOL +WINAPI +CertVerifyCRLRevocation( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pCertId, + _In_ DWORD cCrlInfo, + _In_reads_(cCrlInfo) PCRL_INFO rgpCrlInfo[]); + +BOOL +WINAPI +CertVerifySubjectCertificateContext( + _In_ PCCERT_CONTEXT pSubject, + _In_opt_ PCCERT_CONTEXT pIssuer, + _Inout_ DWORD *pdwFlags); + +LONG +WINAPI +CertVerifyCRLTimeValidity( + _In_opt_ LPFILETIME pTimeToVerify, + _In_ PCRL_INFO pCrlInfo); + +LONG +WINAPI +CertVerifyTimeValidity( + _In_opt_ LPFILETIME pTimeToVerify, + _In_ PCERT_INFO pCertInfo); + +BOOL +WINAPI +CertVerifyValidityNesting( + _In_ PCERT_INFO pSubjectInfo, + _In_ PCERT_INFO pIssuerInfo); + +BOOL +WINAPI +CertVerifyCTLUsage( + _In_ DWORD dwEncodingType, + _In_ DWORD dwSubjectType, + _In_ void *pvSubject, + _In_ PCTL_USAGE pSubjectUsage, + _In_ DWORD dwFlags, + _In_opt_ PCTL_VERIFY_USAGE_PARA pVerifyUsagePara, + _Inout_ PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus); + +BOOL +WINAPI +CertVerifyRevocation( + _In_ DWORD dwEncodingType, + _In_ DWORD dwRevType, + _In_ DWORD cContext, + _In_reads_(cContext) PVOID rgpvContext[], + _In_ DWORD dwFlags, + _In_opt_ PCERT_REVOCATION_PARA pRevPara, + _Inout_ PCERT_REVOCATION_STATUS pRevStatus); + +BOOL +WINAPI +CryptExportPublicKeyInfo( + _In_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + _In_opt_ DWORD dwKeySpec, + _In_ DWORD dwCertEncodingType, + _Out_writes_bytes_to_opt_(*pcbInfo, *pcbInfo) PCERT_PUBLIC_KEY_INFO pInfo, + _Inout_ DWORD *pcbInfo); + +BOOL +WINAPI +CryptExportPublicKeyInfoEx( + _In_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + _In_opt_ DWORD dwKeySpec, + _In_ DWORD dwCertEncodingType, + _In_opt_ LPSTR pszPublicKeyObjId, + _In_ DWORD dwFlags, + _In_opt_ void *pvAuxInfo, + _Out_writes_bytes_to_opt_(*pcbInfo, *pcbInfo) PCERT_PUBLIC_KEY_INFO pInfo, + _Inout_ DWORD *pcbInfo); + +BOOL +WINAPI +CryptImportPublicKeyInfo( + _In_ HCRYPTPROV hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pInfo, + _Out_ HCRYPTKEY *phKey); + +BOOL +WINAPI +CryptImportPublicKeyInfoEx( + _In_ HCRYPTPROV hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pInfo, + _In_ ALG_ID aiKeyAlg, + _In_ DWORD dwFlags, + _In_opt_ void *pvAuxInfo, + _Out_ HCRYPTKEY *phKey); + +BOOL +WINAPI +CryptAcquireCertificatePrivateKey( + _In_ PCCERT_CONTEXT pCert, + _In_ DWORD dwFlags, + _In_opt_ void *pvParameters, + _Out_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProvOrNCryptKey, + _Out_opt_ DWORD *pdwKeySpec, + _Out_opt_ BOOL *pfCallerFreeProvOrNCryptKey); + +BOOL +WINAPI +CryptFindCertificateKeyProvInfo( + _In_ PCCERT_CONTEXT pCert, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); BOOL WINAPI CryptProtectData( DATA_BLOB* pDataIn, LPCWSTR szDataDescr, DATA_BLOB* pOptionalEntropy, PVOID pvReserved, @@ -4371,198 +5506,523 @@ BOOL WINAPI CryptUnprotectData( DATA_BLOB* pDataIn, LPWSTR* ppszDataDescr, DATA_BLOB* pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags, DATA_BLOB* pDataOut ); -DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, void *pvTypePara, LPSTR pszNameString, DWORD cchNameString); -DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString); +DWORD +WINAPI +CertGetNameStringA( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwType, + _In_ DWORD dwFlags, + _In_opt_ void *pvTypePara, + _Out_writes_to_opt_(cchNameString, return) LPSTR pszNameString, + _In_ DWORD cchNameString); + +DWORD +WINAPI +CertGetNameStringW( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwType, + _In_ DWORD dwFlags, + _In_opt_ void *pvTypePara, + _Out_writes_to_opt_(cchNameString, return) LPWSTR pszNameString, + _In_ DWORD cchNameString); + #define CertGetNameString WINELIB_NAME_AW(CertGetNameString) -DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, - LPSTR psz, DWORD csz); -DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, - LPWSTR psz, DWORD csz); +DWORD +WINAPI +CertRDNValueToStrA( + _In_ DWORD dwValueType, + _In_ PCERT_RDN_VALUE_BLOB pValue, + _Out_writes_to_opt_(csz, return) LPSTR psz, + _In_ DWORD csz); + +DWORD +WINAPI +CertRDNValueToStrW( + _In_ DWORD dwValueType, + _In_ PCERT_RDN_VALUE_BLOB pValue, + _Out_writes_to_opt_(csz, return) LPWSTR psz, + _In_ DWORD csz); + #define CertRDNValueToStr WINELIB_NAME_AW(CertRDNValueToStr) -DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, - DWORD dwStrType, LPSTR psz, DWORD csz); -DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, - DWORD dwStrType, LPWSTR psz, DWORD csz); +DWORD +WINAPI +CertNameToStrA( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_NAME_BLOB pName, + _In_ DWORD dwStrType, + _Out_writes_to_opt_(csz, return) LPSTR psz, + _In_ DWORD csz); + +DWORD +WINAPI +CertNameToStrW( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_NAME_BLOB pName, + _In_ DWORD dwStrType, + _Out_writes_to_opt_(csz, return) LPWSTR psz, + _In_ DWORD csz); + #define CertNameToStr WINELIB_NAME_AW(CertNameToStr) -BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500, - DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, - LPCSTR *ppszError); -BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500, - DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, - LPCWSTR *ppszError); +BOOL +WINAPI +CertStrToNameA( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR pszX500, + _In_ DWORD dwStrType, + _Reserved_ void *pvReserved, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded, + _Outptr_opt_result_maybenull_ LPCSTR *ppszError); + +BOOL +WINAPI +CertStrToNameW( + _In_ DWORD dwCertEncodingType, + _In_ LPCWSTR pszX500, + _In_ DWORD dwStrType, + _Reserved_ void *pvReserved, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded, + _Outptr_opt_result_maybenull_ LPCWSTR *ppszError); + #define CertStrToName WINELIB_NAME_AW(CertStrToName) -DWORD WINAPI CryptMsgCalculateEncodedLength(DWORD dwMsgEncodingType, - DWORD dwFlags, DWORD dwMsgType, const void *pvMsgEncodeInfo, - LPSTR pszInnerContentObjID, DWORD cbData); +DWORD +WINAPI +CryptMsgCalculateEncodedLength( + _In_ DWORD dwMsgEncodingType, + _In_ DWORD dwFlags, + _In_ DWORD dwMsgType, + _In_ void const *pvMsgEncodeInfo, + _In_opt_ LPSTR pszInnerContentObjID, + _In_ DWORD cbData); -BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg); +BOOL WINAPI CryptMsgClose(_In_opt_ HCRYPTMSG hCryptMsg); -BOOL WINAPI CryptMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags, - DWORD dwCtrlType, const void *pvCtrlPara); +BOOL +WINAPI +CryptMsgControl( + _In_ HCRYPTMSG hCryptMsg, + _In_ DWORD dwFlags, + _In_ DWORD dwCtrlType, + _In_opt_ void const *pvCtrlPara); -BOOL WINAPI CryptMsgCountersign(HCRYPTMSG hCryptMsg, DWORD dwIndex, - DWORD dwCountersigners, PCMSG_SIGNER_ENCODE_INFO rgCountersigners); +BOOL +WINAPI +CryptMsgCountersign( + _In_ HCRYPTMSG hCryptMsg, + _In_ DWORD dwIndex, + _In_ DWORD cCountersigners, + _In_reads_(cCountersigners) PCMSG_SIGNER_ENCODE_INFO rgCountersigners); -BOOL WINAPI CryptMsgCountersignEncoded(DWORD dwEncodingType, PBYTE pbSignerInfo, - DWORD cbSignerInfo, DWORD cCountersigners, - PCMSG_SIGNER_ENCODE_INFO rgCountersigners, PBYTE pbCountersignature, - PDWORD pcbCountersignature); +BOOL +WINAPI +CryptMsgCountersignEncoded( + _In_ DWORD dwEncodingType, + _In_reads_bytes_(cbSignerInfo) PBYTE pbSignerInfo, + _In_ DWORD cbSignerInfo, + _In_ DWORD cCountersigners, + _In_reads_(cCountersigners) PCMSG_SIGNER_ENCODE_INFO rgCountersigners, + _Out_writes_bytes_to_opt_(*pcbCountersignature, *pcbCountersignature) PBYTE pbCountersignature, + _Inout_ PDWORD pcbCountersignature); -HCRYPTMSG WINAPI CryptMsgDuplicate(HCRYPTMSG hCryptMsg); +HCRYPTMSG WINAPI CryptMsgDuplicate(_In_opt_ HCRYPTMSG hCryptMsg); -BOOL WINAPI CryptMsgEncodeAndSignCTL(DWORD dwMsgEncodingType, - PCTL_INFO pCtlInfo, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags, - BYTE *pbEncoded, DWORD *pcbEncoded); +BOOL +WINAPI +CryptMsgEncodeAndSignCTL( + _In_ DWORD dwMsgEncodingType, + _In_ PCTL_INFO pCtlInfo, + _In_ PCMSG_SIGNED_ENCODE_INFO pSignInfo, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptMsgGetAndVerifySigner(HCRYPTMSG hCryptMsg, DWORD cSignerStore, - HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT *ppSigner, - DWORD *pdwSignerIndex); +_Success_(return == 0) +BOOL +WINAPI +CryptMsgGetAndVerifySigner( + _In_ HCRYPTMSG hCryptMsg, + _In_ DWORD cSignerStore, + _In_reads_opt_(cSignerStore) HCERTSTORE *rghSignerStore, + _In_ DWORD dwFlags, + _Outptr_opt_ PCCERT_CONTEXT *ppSigner, + _Inout_opt_ DWORD *pdwSignerIndex); -BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, - DWORD dwIndex, void *pvData, DWORD *pcbData); +BOOL +WINAPI +CryptMsgGetParam( + _In_ HCRYPTMSG hCryptMsg, + _In_ DWORD dwParamType, + _In_ DWORD dwIndex, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags, - DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo, - PCMSG_STREAM_INFO pStreamInfo); +HCRYPTMSG +WINAPI +CryptMsgOpenToDecode( + _In_ DWORD dwMsgEncodingType, + _In_ DWORD dwFlags, + _In_ DWORD dwMsgType, + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _Reserved_ PCERT_INFO pRecipientInfo, + _In_opt_ PCMSG_STREAM_INFO pStreamInfo); -HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags, - DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID, - PCMSG_STREAM_INFO pStreamInfo); +HCRYPTMSG +WINAPI +CryptMsgOpenToEncode( + _In_ DWORD dwMsgEncodingType, + _In_ DWORD dwFlags, + _In_ DWORD dwMsgType, + _In_ void const *pvMsgEncodeInfo, + _In_opt_ LPSTR pszInnerContentObjID, + _In_opt_ PCMSG_STREAM_INFO pStreamInfo); -BOOL WINAPI CryptMsgSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent, - DWORD cbCtlContent, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags, - BYTE *pbEncoded, DWORD *pcbEncoded); +BOOL +WINAPI +CryptMsgSignCTL( + _In_ DWORD dwMsgEncodingType, + _In_reads_bytes_(cbCtlContent) BYTE *pbCtlContent, + _In_ DWORD cbCtlContent, + _In_ PCMSG_SIGNED_ENCODE_INFO pSignInfo, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData, - DWORD cbData, BOOL fFinal); +BOOL +WINAPI +CryptMsgUpdate( + _In_ HCRYPTMSG hCryptMsg, + _In_reads_bytes_opt_(cbData) const BYTE *pbData, + _In_ DWORD cbData, + _In_ BOOL fFinal); -BOOL WINAPI CryptMsgVerifyCountersignatureEncoded(HCRYPTPROV_LEGACY hCryptProv, - DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo, - PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature, - PCERT_INFO pciCountersigner); +BOOL +WINAPI +CryptMsgVerifyCountersignatureEncoded( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwEncodingType, + _In_reads_bytes_(cbSignerInfo) PBYTE pbSignerInfo, + _In_ DWORD cbSignerInfo, + _In_reads_bytes_(cbSignerInfoCountersignature) PBYTE pbSignerInfoCountersignature, + _In_ DWORD cbSignerInfoCountersignature, + _In_ PCERT_INFO pciCountersigner); -BOOL WINAPI CryptMsgVerifyCountersignatureEncodedEx(HCRYPTPROV_LEGACY hCryptProv, - DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo, - PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature, - DWORD dwSignerType, void *pvSigner, DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptMsgVerifyCountersignatureEncodedEx( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwEncodingType, + _In_reads_bytes_(cbSignerInfo) PBYTE pbSignerInfo, + _In_ DWORD cbSignerInfo, + _In_reads_bytes_(cbSignerInfoCountersignature) PBYTE pbSignerInfoCountersignature, + _In_ DWORD cbSignerInfoCountersignature, + _In_ DWORD dwSignerType, + _In_ void *pvSigner, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvExtra); -BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara, - BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[], - DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob); -BOOL WINAPI CryptSignMessageWithKey(PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara, - const BYTE *pbToBeSigned, DWORD cbToBeSigned, BYTE *pbSignedBlob, - DWORD *pcbSignedBlob); +BOOL +WINAPI +CryptSignMessage( + _In_ PCRYPT_SIGN_MESSAGE_PARA pSignPara, + _In_ BOOL fDetachedSignature, + _In_ DWORD cToBeSigned, + _In_reads_opt_(cToBeSigned) const BYTE *rgpbToBeSigned[], + _In_reads_(cToBeSigned) DWORD rgcbToBeSigned[], + _Out_writes_bytes_to_opt_(*pcbSignedBlob, *pcbSignedBlob) BYTE *pbSignedBlob, + _Inout_ DWORD *pcbSignedBlob); -BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, - DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob, - BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert); -BOOL WINAPI CryptVerifyMessageSignatureWithKey( - PCRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara, - PCERT_PUBLIC_KEY_INFO pPublicKeyInfo, const BYTE *pbSignedBlob, - DWORD cbSignedBlob, BYTE *pbDecoded, DWORD *pcbDecoded); +BOOL +WINAPI +CryptSignMessageWithKey( + _In_ PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara, + _In_reads_bytes_(cbToBeSigned) const BYTE *pbToBeSigned, + _In_ DWORD cbToBeSigned, + _Out_writes_bytes_to_opt_(*pcbSignedBlob, *pcbSignedBlob) BYTE *pbSignedBlob, + _Inout_ DWORD *pcbSignedBlob); -BOOL WINAPI CryptVerifyDetachedMessageSignature( - PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, - const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned, - const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[], - PCCERT_CONTEXT *ppSignerCert); -LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType, - const BYTE *pbSignedBlob, DWORD cbSignedBlob); +BOOL +WINAPI +CryptVerifyMessageSignature( + _In_ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, + _In_ DWORD dwSignerIndex, + _In_reads_bytes_(cbSignedBlob) const BYTE *pbSignedBlob, + _In_ DWORD cbSignedBlob, + _Out_writes_bytes_to_opt_(*pcbDecoded, *pcbDecoded) BYTE *pbDecoded, + _Inout_opt_ DWORD *pcbDecoded, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppSignerCert); -BOOL WINAPI CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, - DWORD cRecipientCert, PCCERT_CONTEXT rgpRecipientCert[], - const BYTE *pbToBeEncrypted, DWORD cbToBeEncrypted, BYTE *pbEncryptedBlob, - DWORD *pcbEncryptedBlob); -BOOL WINAPI CryptDecryptMessage(PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, - const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted, - DWORD *pcbDecrypted, PCCERT_CONTEXT *ppXchgCert); +BOOL +WINAPI +CryptVerifyMessageSignatureWithKey( + _In_ PCRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara, + _In_opt_ PCERT_PUBLIC_KEY_INFO pPublicKeyInfo, + _In_reads_bytes_(cbSignedBlob) const BYTE *pbSignedBlob, + _In_ DWORD cbSignedBlob, + _Out_writes_bytes_to_opt_(*pcbDecoded, *pcbDecoded) BYTE *pbDecoded, + _Inout_opt_ DWORD *pcbDecoded); -BOOL WINAPI CryptSignAndEncryptMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara, - PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, DWORD cRecipientCert, - PCCERT_CONTEXT rgpRecipientCert[], const BYTE *pbToBeSignedAndEncrypted, - DWORD cbToBeSignedAndEncrypted, BYTE *pbSignedAndEncryptedBlob, - DWORD *pcbSignedAndEncryptedBlob); -BOOL WINAPI CryptDecryptAndVerifyMessageSignature( - PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, - PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, - const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted, - DWORD *pcbDecrypted, PCCERT_CONTEXT *ppXchgCert, PCCERT_CONTEXT *ppSignerCert); +BOOL +WINAPI +CryptVerifyDetachedMessageSignature( + _In_ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, + _In_ DWORD dwSignerIndex, + _In_reads_bytes_(cbDetachedSignBlob) const BYTE *pbDetachedSignBlob, + _In_ DWORD cbDetachedSignBlob, + _In_ DWORD cToBeSigned, + _In_reads_(cToBeSigned) const BYTE *rgpbToBeSigned[], + _In_reads_(cToBeSigned) DWORD rgcbToBeSigned[], + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppSignerCert); -HCERTSTORE WINAPI CryptGetMessageCertificates(DWORD dwMsgAndCertEncodingType, - HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const BYTE *pbSignedBlob, - DWORD cbSignedBlob); +LONG +WINAPI +CryptGetMessageSignerCount( + _In_ DWORD dwMsgEncodingType, + _In_reads_bytes_(cbSignedBlob) const BYTE *pbSignedBlob, + _In_ DWORD cbSignedBlob); -BOOL WINAPI CryptDecodeMessage(DWORD dwMsgTypeFlags, - PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, - PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, - const BYTE *pbEncodedBlob, DWORD cbEncodedBlob, DWORD dwPrevInnerContentType, - DWORD *pdwMsgType, DWORD *pdwInnerContentType, BYTE *pbDecoded, - DWORD *pcbDecoded, PCCERT_CONTEXT *ppXchgCert, PCCERT_CONTEXT *ppSignerCert); +BOOL +WINAPI +CryptEncryptMessage( + _In_ PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, + _In_ DWORD cRecipientCert, + _In_reads_(cRecipientCert) PCCERT_CONTEXT rgpRecipientCert[], + _In_reads_bytes_opt_(cbToBeEncrypted) const BYTE *pbToBeEncrypted, + _In_ DWORD cbToBeEncrypted, + _Out_writes_bytes_to_opt_(*pcbEncryptedBlob, *pcbEncryptedBlob) BYTE *pbEncryptedBlob, + _Inout_ DWORD *pcbEncryptedBlob); -BOOL WINAPI CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara, - BOOL fDetachedHash, DWORD cToBeHashed, const BYTE *rgpbToBeHashed[], - DWORD rgcbToBeHashed[], BYTE *pbHashedBlob, DWORD *pcbHashedBlob, - BYTE *pbComputedHash, DWORD *pcbComputedHash); -BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, - BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed, - DWORD *pcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash); -BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, - BYTE *pbDetachedHashBlob, DWORD cbDetachedHashBlob, DWORD cToBeHashed, - const BYTE *rgpbToBeHashed[], DWORD rgcbToBeHashed[], BYTE *pbComputedHash, - DWORD *pcbComputedHash); +BOOL +WINAPI +CryptDecryptMessage( + _In_ PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, + _In_reads_bytes_(cbEncryptedBlob) const BYTE *pbEncryptedBlob, + _In_ DWORD cbEncryptedBlob, + _Out_writes_bytes_to_opt_(*pcbDecrypted, *pcbDecrypted) BYTE *pbDecrypted, + _Inout_opt_ DWORD *pcbDecrypted, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppXchgCert); + +BOOL +WINAPI +CryptSignAndEncryptMessage( + _In_ PCRYPT_SIGN_MESSAGE_PARA pSignPara, + _In_ PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, + _In_ DWORD cRecipientCert, + _In_reads_(cRecipientCert) PCCERT_CONTEXT rgpRecipientCert[], + _In_reads_bytes_(cbToBeSignedAndEncrypted) const BYTE *pbToBeSignedAndEncrypted, + _In_ DWORD cbToBeSignedAndEncrypted, + _Out_writes_bytes_to_opt_(*pcbSignedAndEncryptedBlob, *pcbSignedAndEncryptedBlob) BYTE *pbSignedAndEncryptedBlob, + _Inout_ DWORD *pcbSignedAndEncryptedBlob); + +BOOL +WINAPI +CryptDecryptAndVerifyMessageSignature( + _In_ PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, + _In_ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, + _In_ DWORD dwSignerIndex, + _In_reads_bytes_(cbEncryptedBlob) const BYTE *pbEncryptedBlob, + _In_ DWORD cbEncryptedBlob, + _Out_writes_bytes_to_opt_(*pcbDecrypted, *pcbDecrypted) BYTE *pbDecrypted, + _Inout_opt_ DWORD *pcbDecrypted, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppXchgCert, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppSignerCert); + +HCERTSTORE +WINAPI +CryptGetMessageCertificates( + _In_ DWORD dwMsgAndCertEncodingType, + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwFlags, + _In_reads_bytes_(cbSignedBlob) const BYTE *pbSignedBlob, + _In_ DWORD cbSignedBlob); + +BOOL +WINAPI +CryptDecodeMessage( + _In_ DWORD dwMsgTypeFlags, + _In_opt_ PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, + _In_opt_ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, + _In_ DWORD dwSignerIndex, + _In_reads_bytes_(cbEncodedBlob) const BYTE *pbEncodedBlob, + _In_ DWORD cbEncodedBlob, + _In_ DWORD dwPrevInnerContentType, + _Out_opt_ DWORD *pdwMsgType, + _Out_opt_ DWORD *pdwInnerContentType, + _Out_writes_bytes_to_opt_(*pcbDecoded, *pcbDecoded) BYTE *pbDecoded, + _Inout_opt_ DWORD *pcbDecoded, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppXchgCert, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppSignerCert); + +BOOL +WINAPI +CryptHashMessage( + _In_ PCRYPT_HASH_MESSAGE_PARA pHashPara, + _In_ BOOL fDetachedHash, + _In_ DWORD cToBeHashed, + _In_reads_(cToBeHashed) const BYTE *rgpbToBeHashed[], + _In_reads_(cToBeHashed) DWORD rgcbToBeHashed[], + _Out_writes_bytes_to_opt_(*pcbHashedBlob, *pcbHashedBlob) BYTE *pbHashedBlob, + _Inout_opt_ DWORD *pcbHashedBlob, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_opt_ DWORD *pcbComputedHash); + +BOOL +WINAPI +CryptVerifyMessageHash( + _In_ PCRYPT_HASH_MESSAGE_PARA pHashPara, + _In_reads_bytes_(cbHashedBlob) BYTE *pbHashedBlob, + _In_ DWORD cbHashedBlob, + _Out_writes_bytes_to_opt_(*pcbToBeHashed, *pcbToBeHashed) BYTE *pbToBeHashed, + _Inout_opt_ DWORD *pcbToBeHashed, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_opt_ DWORD *pcbComputedHash); + +BOOL +WINAPI +CryptVerifyDetachedMessageHash( + _In_ PCRYPT_HASH_MESSAGE_PARA pHashPara, + _In_reads_bytes_(cbDetachedHashBlob) BYTE *pbDetachedHashBlob, + _In_ DWORD cbDetachedHashBlob, + _In_ DWORD cToBeHashed, + _In_reads_(cToBeHashed) const BYTE *rgpbToBeHashed[], + _In_reads_(cToBeHashed) DWORD rgcbToBeHashed[], + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_opt_ DWORD *pcbComputedHash); /* PFX functions */ -HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, - DWORD dwFlags); -BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX); -BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, - DWORD dwFlags); -BOOL WINAPI PFXExportCertStoreEx(HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX, - LPCWSTR szPassword, void *pvReserved, DWORD dwFlags); -BOOL WINAPI PFXExportCertStore(HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX, - LPCWSTR szPassword, DWORD dwFlags); +HCERTSTORE +WINAPI +PFXImportCertStore( + _In_ CRYPT_DATA_BLOB *pPFX, + _In_ LPCWSTR szPassword, + _In_ DWORD dwFlags); + +BOOL WINAPI PFXIsPFXBlob(_In_ CRYPT_DATA_BLOB *pPFX); + +BOOL +WINAPI +PFXVerifyPassword( + _In_ CRYPT_DATA_BLOB *pPFX, + _In_ LPCWSTR szPassword, + _In_ DWORD dwFlags); + +BOOL +WINAPI +PFXExportCertStoreEx( + _In_ HCERTSTORE hStore, + _Inout_ CRYPT_DATA_BLOB* pPFX, + _In_ LPCWSTR szPassword, + _In_ void* pvPara, + _In_ DWORD dwFlags); + +BOOL +WINAPI +PFXExportCertStore( + _In_ HCERTSTORE hStore, + _Inout_ CRYPT_DATA_BLOB* pPFX, + _In_ LPCWSTR szPassword, + _In_ DWORD dwFlags); + BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, DWORD dwFlags); /* cryptnet.dll functions */ -BOOL WINAPI CryptCancelAsyncRetrieval(HCRYPTASYNC hAsyncRetrieval); +BOOL WINAPI CryptCancelAsyncRetrieval(_In_opt_ HCRYPTASYNC hAsyncRetrieval); -BOOL WINAPI CryptGetObjectUrl(LPCSTR pszUrlOid, LPVOID pvPara, DWORD dwFlags, - PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, PCRYPT_URL_INFO pUrlInfo, - DWORD *pcbUrlInfo, LPVOID pvReserved); +BOOL +WINAPI +CryptGetObjectUrl( + _In_ LPCSTR pszUrlOid, + _In_ LPVOID pvPara, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbUrlArray, *pcbUrlArray) PCRYPT_URL_ARRAY pUrlArray, + _Inout_ DWORD* pcbUrlArray, + _Out_writes_bytes_to_opt_(*pcbUrlInfo, *pcbUrlInfo) PCRYPT_URL_INFO pUrlInfo, + _Inout_opt_ DWORD* pcbUrlInfo, + _Reserved_ LPVOID pvReserved); -BOOL WINAPI CryptGetTimeValidObject(LPCSTR pszTimeValidOid, void *pvPara, - PCCERT_CONTEXT pIssuer, LPFILETIME pftValidFor, DWORD dwFlags, DWORD dwTimeout, - void **ppvObject, PCRYPT_CREDENTIALS pCredentials, void *pvReserved); +_Success_(return != 0) +BOOL +WINAPI +CryptGetTimeValidObject( + _In_ LPCSTR pszTimeValidOid, + _In_ void *pvPara, + _In_ PCCERT_CONTEXT pIssuer, + _In_opt_ LPFILETIME pftValidFor, + _In_ DWORD dwFlags, + _In_ DWORD dwTimeout, + _Outptr_opt_ void **ppvObject, + _In_opt_ PCRYPT_CREDENTIALS pCredentials, + _Inout_opt_ void *pvReserved); -BOOL WINAPI CryptFlushTimeValidObject(LPCSTR pszFlushTimeValidOid, void *pvPara, - PCCERT_CONTEXT pIssuer, DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptFlushTimeValidObject( + _In_ LPCSTR pszFlushTimeValidOid, + _In_ void *pvPara, + _In_ PCCERT_CONTEXT pIssuer, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); -BOOL WINAPI CryptInstallCancelRetrieval(PFN_CRYPT_CANCEL_RETRIEVAL pfnCancel, - const void *pvArg, DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptInstallCancelRetrieval( + __callback PFN_CRYPT_CANCEL_RETRIEVAL pfnCancel, + _In_opt_ const void *pvArg, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); -BOOL WINAPI CryptUninstallCancelRetrieval(DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptUninstallCancelRetrieval( + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); + +_Success_(return != 0) +BOOL +WINAPI +CryptRetrieveObjectByUrlA( + _In_ LPCSTR pszUrl, + _In_opt_ LPCSTR pszObjectOid, + _In_ DWORD dwRetrievalFlags, + _In_ DWORD dwTimeout, + _Outptr_ LPVOID* ppvObject, + _In_opt_ HCRYPTASYNC hAsyncRetrieve, + _In_opt_ PCRYPT_CREDENTIALS pCredentials, + _In_opt_ LPVOID pvVerify, + _Inout_opt_ PCRYPT_RETRIEVE_AUX_INFO pAuxInfo); + +_Success_(return != 0) +BOOL +WINAPI +CryptRetrieveObjectByUrlW( + _In_ LPCWSTR pszUrl, + _In_opt_ LPCSTR pszObjectOid, + _In_ DWORD dwRetrievalFlags, + _In_ DWORD dwTimeout, + _Outptr_ LPVOID* ppvObject, + _In_opt_ HCRYPTASYNC hAsyncRetrieve, + _In_opt_ PCRYPT_CREDENTIALS pCredentials, + _In_opt_ LPVOID pvVerify, + _Inout_opt_ PCRYPT_RETRIEVE_AUX_INFO pAuxInfo); -BOOL WINAPI CryptRetrieveObjectByUrlA(LPCSTR pszURL, LPCSTR pszObjectOid, - DWORD dwRetrievalFlags, DWORD dwTimeout, LPVOID *ppvObject, - HCRYPTASYNC hAsyncRetrieve, PCRYPT_CREDENTIALS pCredentials, LPVOID pvVerify, - PCRYPT_RETRIEVE_AUX_INFO pAuxInfo); -BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid, - DWORD dwRetrievalFlags, DWORD dwTimeout, LPVOID *ppvObject, - HCRYPTASYNC hAsyncRetrieve, PCRYPT_CREDENTIALS pCredentials, LPVOID pvVerify, - PCRYPT_RETRIEVE_AUX_INFO pAuxInfo); #define CryptRetrieveObjectByUrl WINELIB_NAME_AW(CryptRetrieveObjectByUrl) /* Not found in crypt32.dll but in softpub.dll */ -HRESULT WINAPI FindCertsByIssuer(PCERT_CHAIN pCertChains, DWORD *pcbCertChains, - DWORD *pcCertChains, BYTE* pbEncodedIssuerName, DWORD cbEncodedIssuerName, - LPCWSTR pwszPurpose, DWORD dwKeySpec); +HRESULT +WINAPI +FindCertsByIssuer( + _Out_writes_bytes_to_opt_(*pcbCertChains, *pcbCertChains) PCERT_CHAIN pCertChains, + _Inout_ DWORD *pcbCertChains, + _Out_ DWORD *pcCertChains, + _In_reads_bytes_opt_(cbEncodedIssuerName) BYTE* pbEncodedIssuerName, + _In_ DWORD cbEncodedIssuerName, + _In_opt_ LPCWSTR pwszPurpose, + _In_ DWORD dwKeySpec); #ifdef _MSC_VER #pragma warning(pop) From dcff1c6eb9da5fd6a0fd4aa09ad333b06c6a84c1 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 6 Aug 2013 16:16:27 +0000 Subject: [PATCH 19/25] [CRT] * Annotate time.h. svn path=/trunk/; revision=59656 --- reactos/include/crt/time.h | 330 +++++++++++++++++++++++++++++++------ 1 file changed, 279 insertions(+), 51 deletions(-) diff --git a/reactos/include/crt/time.h b/reactos/include/crt/time.h index b868ab9d8e9..d332eb4ba84 100644 --- a/reactos/include/crt/time.h +++ b/reactos/include/crt/time.h @@ -3,6 +3,7 @@ * This file is part of the w64 mingw-runtime package. * No warranty is given; refer to the file DISCLAIMER within this package. */ + #ifndef _TIME_H_ #define _TIME_H_ @@ -92,67 +93,295 @@ extern "C" { _CRTDATA(extern long _timezone); _CRTDATA(extern char * _tzname[2]); - _CRTIMP errno_t __cdecl _get_daylight(int *_Daylight); - _CRTIMP errno_t __cdecl _get_dstbias(long *_Daylight_savings_bias); - _CRTIMP errno_t __cdecl _get_timezone(long *_Timezone); - _CRTIMP errno_t __cdecl _get_tzname(size_t *_ReturnValue,char *_Buffer,size_t _SizeInBytes,int _Index); + _CRTIMP errno_t __cdecl _get_daylight(_Out_ int *_Daylight); + _CRTIMP errno_t __cdecl _get_dstbias(_Out_ long *_Daylight_savings_bias); + _CRTIMP errno_t __cdecl _get_timezone(_Out_ long *_Timezone); - _CRTIMP _CRT_INSECURE_DEPRECATE(asctime_s) char *__cdecl asctime(const struct tm *_Tm); - _CRTIMP _CRT_INSECURE_DEPRECATE(_ctime32_s) char *__cdecl _ctime32(const __time32_t *_Time); - _CRTIMP clock_t __cdecl clock(void); - _CRTIMP double __cdecl _difftime32(__time32_t _Time1,__time32_t _Time2); - _CRTIMP _CRT_INSECURE_DEPRECATE(_gmtime32_s) struct tm *__cdecl _gmtime32(const __time32_t *_Time); - _CRTIMP _CRT_INSECURE_DEPRECATE(_localtime32_s) struct tm *__cdecl _localtime32(const __time32_t *_Time); - _CRTIMP size_t __cdecl strftime(char *_Buf,size_t _SizeInBytes,const char *_Format,const struct tm *_Tm); - _CRTIMP size_t __cdecl _strftime_l(char *_Buf,size_t _Max_size,const char *_Format,const struct tm *_Tm,_locale_t _Locale); - _CRTIMP char *__cdecl _strdate(char *_Buffer); - _CRTIMP char *__cdecl _strtime(char *_Buffer); - _CRTIMP __time32_t __cdecl _time32(__time32_t *_Time); - _CRTIMP __time32_t __cdecl _mktime32(struct tm *_Tm); - _CRTIMP __time32_t __cdecl _mkgmtime32(struct tm *_Tm); + _CRTIMP + errno_t + __cdecl + _get_tzname( + _Out_ size_t *_ReturnValue, + _Out_writes_z_(_SizeInBytes) char *_Buffer, + _In_ size_t _SizeInBytes, + _In_ int _Index); + + _Check_return_ + _CRTIMP + _CRT_INSECURE_DEPRECATE(asctime_s) + char * + __cdecl + asctime( + _In_ const struct tm *_Tm); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_ctime32_s) + char * + __cdecl + _ctime32( + _In_ const __time32_t *_Time); + + _Check_return_ _CRTIMP clock_t __cdecl clock(void); + + _CRTIMP + double + __cdecl + _difftime32( + _In_ __time32_t _Time1, + _In_ __time32_t _Time2); + + _Check_return_ + _CRTIMP + _CRT_INSECURE_DEPRECATE(_gmtime32_s) + struct tm * + __cdecl + _gmtime32( + _In_ const __time32_t *_Time); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_localtime32_s) + struct tm * + __cdecl + _localtime32( + _In_ const __time32_t *_Time); + + _Success_(return > 0) + _CRTIMP + size_t + __cdecl + strftime( + _Out_writes_z_(_SizeInBytes) char *_Buf, + _In_ size_t _SizeInBytes, + _In_z_ _Printf_format_string_ const char *_Format, + _In_ const struct tm *_Tm); + + _Success_(return > 0) + _CRTIMP + size_t + __cdecl + _strftime_l( + _Out_writes_z_(_Max_size) char *_Buf, + _In_ size_t _Max_size, + _In_z_ _Printf_format_string_ const char *_Format, + _In_ const struct tm *_Tm, + _In_opt_ _locale_t _Locale); + + _CRTIMP char *__cdecl _strdate(_Out_writes_z_(9) char *_Buffer); + _CRTIMP char *__cdecl _strtime(_Out_writes_z_(9) char *_Buffer); + _CRTIMP __time32_t __cdecl _time32(_Out_opt_ __time32_t *_Time); + _CRTIMP __time32_t __cdecl _mktime32(_Inout_ struct tm *_Tm); + _CRTIMP __time32_t __cdecl _mkgmtime32(_Inout_ struct tm *_Tm); _CRTIMP void __cdecl _tzset(void); - _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _getsystime(struct tm *_Tm); - _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _setsystime(struct tm *_Tm,unsigned _MilliSec); + _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _getsystime(_Out_ struct tm *_Tm); - _CRTIMP errno_t __cdecl asctime_s(char *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _strdate_s(char *_Buf,size_t _SizeInBytes); - _CRTIMP errno_t __cdecl _strtime_s(char *_Buf ,size_t _SizeInBytes); + _CRT_OBSOLETE(GetLocalTime) + unsigned + __cdecl + _setsystime( + _In_ struct tm *_Tm, + unsigned _MilliSec); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + asctime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf, + _In_range_(>= , 26) size_t _SizeInBytes, + _In_ const struct tm *_Tm); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _ctime32_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf, + _In_ size_t _SizeInBytes, + _In_ const __time32_t *_Time); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _gmtime32_s( + _In_ struct tm *_Tm, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _localtime32_s( + _Out_ struct tm *_Tm, + _In_ const __time32_t *_Time); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _strdate_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf, + _In_range_(>= , 9) size_t _SizeInBytes); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _strtime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf, + _In_range_(>= , 9) size_t _SizeInBytes); #if _INTEGRAL_MAX_BITS >= 64 - _CRTIMP double __cdecl _difftime64(__time64_t _Time1,__time64_t _Time2); - _CRTIMP _CRT_INSECURE_DEPRECATE(_ctime64_s) char *__cdecl _ctime64(const __time64_t *_Time); - _CRTIMP _CRT_INSECURE_DEPRECATE(_gmtime64_s) struct tm *__cdecl _gmtime64(const __time64_t *_Time); - _CRTIMP _CRT_INSECURE_DEPRECATE(_localtime64_s) struct tm *__cdecl _localtime64(const __time64_t *_Time); - _CRTIMP __time64_t __cdecl _mktime64(struct tm *_Tm); - _CRTIMP __time64_t __cdecl _mkgmtime64(struct tm *_Tm); - _CRTIMP __time64_t __cdecl _time64(__time64_t *_Time); - _CRTIMP errno_t __cdecl _ctime64_s(char *_Buf,size_t _SizeInBytes,const __time64_t *_Time); - _CRTIMP errno_t __cdecl _gmtime64_s(struct tm *_Tm,const __time64_t *_Time); - _CRTIMP errno_t __cdecl _localtime64_s(struct tm *_Tm,const __time64_t *_Time); -#endif + _Check_return_ + _CRTIMP + double + __cdecl + _difftime64( + _In_ __time64_t _Time1, + _In_ __time64_t _Time2); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_ctime64_s) + char * + __cdecl + _ctime64( + _In_ const __time64_t *_Time); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_gmtime64_s) + struct tm * + __cdecl + _gmtime64( + _In_ const __time64_t *_Time); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_localtime64_s) + struct tm * + __cdecl + _localtime64( + _In_ const __time64_t *_Time); + + _CRTIMP __time64_t __cdecl _mktime64(_Inout_ struct tm *_Tm); + _CRTIMP __time64_t __cdecl _mkgmtime64(_Inout_ struct tm *_Tm); + _CRTIMP __time64_t __cdecl _time64(_Out_opt_ __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _ctime64_s( + _Out_writes_z_(_SizeInBytes) char *_Buf, + _In_ size_t _SizeInBytes, + _In_ const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _gmtime64_s( + _Out_ struct tm *_Tm, + _In_ const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _localtime64_s( + _Out_ struct tm *_Tm, + _In_ const __time64_t *_Time); + +#endif /* _INTEGRAL_MAX_BITS >= 64 */ #ifndef _WTIME_DEFINED #define _WTIME_DEFINED - _CRTIMP _CRT_INSECURE_DEPRECATE(_wasctime_s) wchar_t *__cdecl _wasctime(const struct tm *_Tm); - _CRTIMP wchar_t *__cdecl _wctime(const time_t *_Time); - _CRTIMP _CRT_INSECURE_DEPRECATE(_wctime32_s) wchar_t *__cdecl _wctime32(const __time32_t *_Time); - _CRTIMP size_t __cdecl wcsftime(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm); - _CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale); - _CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer); - _CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer); - _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); + _CRTIMP + _CRT_INSECURE_DEPRECATE(_wasctime_s) + wchar_t * + __cdecl + _wasctime( + _In_ const struct tm *_Tm); + + _CRTIMP wchar_t *__cdecl _wctime(const time_t *_Time); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_wctime32_s) + wchar_t * + __cdecl + _wctime32( + _In_ const __time32_t *_Time); + + _Success_(return > 0) + _CRTIMP + size_t + __cdecl + wcsftime( + _Out_writes_z_(_SizeInWords) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_ const struct tm *_Tm); + + _Success_(return > 0) + _CRTIMP + size_t + __cdecl + _wcsftime_l( + _Out_writes_z_(_SizeInWords) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_ const struct tm *_Tm, + _In_opt_ _locale_t _Locale); + + _CRTIMP wchar_t *__cdecl _wstrdate(_Out_writes_z_(9) wchar_t *_Buffer); + _CRTIMP wchar_t *__cdecl _wstrtime(_Out_writes_z_(9) wchar_t *_Buffer); + + _CRTIMP + errno_t + __cdecl + _wasctime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_range_(>= , 26) size_t _SizeInWords, + _In_ const struct tm *_Tm); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _wctime32_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wstrdate_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_ size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wstrtime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_range_(>= , 9) size_t _SizeInWords); + #if _INTEGRAL_MAX_BITS >= 64 - _CRTIMP _CRT_INSECURE_DEPRECATE(_wctime64_s) wchar_t *__cdecl _wctime64(const __time64_t *_Time); - _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); -#endif + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_wctime64_s) + wchar_t * + __cdecl + _wctime64( + _In_ const __time64_t *_Time); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _wctime64_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time64_t *_Time); + +#endif /* _INTEGRAL_MAX_BITS >= 64 */ #if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) #define _INC_WTIME_INL @@ -218,4 +447,3 @@ __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); } #pragma pack(pop) #endif /* End _TIME_H_ */ - From e3cc5db0e611b47fa2bc5e586fe2f3a1829613ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 6 Aug 2013 18:36:25 +0000 Subject: [PATCH 20/25] [KERNEL32] Limit indentation by avoiding many "if ()" imbrications. svn path=/trunk/; revision=59657 --- reactos/dll/win32/kernel32/client/proc.c | 44 +++++++++++------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index e72273a45f6..bb2bda4a858 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -60,30 +60,28 @@ StuffStdHandle(IN HANDLE ProcessHandle, { NTSTATUS Status; HANDLE DuplicatedHandle; - SIZE_T Dummy; + SIZE_T NumberOfBytesWritten; - /* Is there a handle to duplicate? */ - if (StandardHandle) - { - /* Duplicate it */ - Status = NtDuplicateObject(NtCurrentProcess(), - StandardHandle, - ProcessHandle, - &DuplicatedHandle, - 0, - 0, - DUPLICATE_SAME_ACCESS | - DUPLICATE_SAME_ATTRIBUTES); - if (NT_SUCCESS(Status)) - { - /* Write it */ - NtWriteVirtualMemory(ProcessHandle, - Address, - &DuplicatedHandle, - sizeof(HANDLE), - &Dummy); - } - } + /* If there is no handle to duplicate, return immediately */ + if (!StandardHandle) return; + + /* Duplicate the handle */ + Status = NtDuplicateObject(NtCurrentProcess(), + StandardHandle, + ProcessHandle, + &DuplicatedHandle, + 0, + 0, + DUPLICATE_SAME_ACCESS | + DUPLICATE_SAME_ATTRIBUTES); + if (!NT_SUCCESS(Status)) return; + + /* Write it */ + NtWriteVirtualMemory(ProcessHandle, + Address, + &DuplicatedHandle, + sizeof(HANDLE), + &NumberOfBytesWritten); } BOOLEAN From 732baee549e8b43f23ec9ba6773f36da1b44c831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 6 Aug 2013 19:10:36 +0000 Subject: [PATCH 21/25] [CONSRV] - Fix console handle validation (triggered by recent Process changes by Alex). - Temporarily add commented-out asserts for testing purposes only. svn path=/trunk/; revision=59658 --- reactos/win32ss/user/winsrv/consrv/condrv/console.c | 13 ++++++++++--- reactos/win32ss/user/winsrv/consrv/console.c | 2 +- reactos/win32ss/user/winsrv/consrv/handle.c | 8 ++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/reactos/win32ss/user/winsrv/consrv/condrv/console.c b/reactos/win32ss/user/winsrv/consrv/condrv/console.c index 861c4721f74..0c4cb6ac9ec 100644 --- a/reactos/win32ss/user/winsrv/consrv/condrv/console.c +++ b/reactos/win32ss/user/winsrv/consrv/condrv/console.c @@ -143,9 +143,13 @@ static NTSTATUS RemoveConsoleByHandle(IN HANDLE Handle) { NTSTATUS Status = STATUS_SUCCESS; - ULONG Index = HandleToULong(Handle) >> 2; PCONSOLE Console; + BOOLEAN ValidHandle = ((HandleToULong(Handle) & 0x3) == 0x3); + ULONG Index = HandleToULong(Handle) >> 2; + + if (!ValidHandle) return STATUS_INVALID_HANDLE; + ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) || (ConsoleList != NULL && ConsoleListSize != 0) ); @@ -339,10 +343,13 @@ ConDrvValidateConsole(OUT PCONSOLE* Console, IN BOOLEAN LockConsole) { BOOLEAN RetVal = FALSE; - - ULONG Index = HandleToULong(ConsoleHandle) >> 2; PCONSOLE ValidatedConsole; + BOOLEAN ValidHandle = ((HandleToULong(ConsoleHandle) & 0x3) == 0x3); + ULONG Index = HandleToULong(ConsoleHandle) >> 2; + + if (!ValidHandle) return FALSE; + if (!Console) return FALSE; *Console = NULL; diff --git a/reactos/win32ss/user/winsrv/consrv/console.c b/reactos/win32ss/user/winsrv/consrv/console.c index 9403daa081f..932d623ff21 100644 --- a/reactos/win32ss/user/winsrv/consrv/console.c +++ b/reactos/win32ss/user/winsrv/consrv/console.c @@ -159,7 +159,7 @@ VOID FASTCALL ConSrvReleaseConsole(PCONSOLE Console, BOOL WasConsoleLocked) { - /* Just call the driver*/ + /* Just call the driver */ ConDrvReleaseConsole(Console, WasConsoleLocked); } diff --git a/reactos/win32ss/user/winsrv/consrv/handle.c b/reactos/win32ss/user/winsrv/consrv/handle.c index f5ef3e755f3..9e6ac97ba3b 100644 --- a/reactos/win32ss/user/winsrv/consrv/handle.c +++ b/reactos/win32ss/user/winsrv/consrv/handle.c @@ -387,6 +387,8 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData, RtlEnterCriticalSection(&ProcessData->HandleTableLock); ASSERT(ProcessData->HandleTable); + // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) || + // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) ); if (Index >= ProcessData->HandleTableSize || (Object = ProcessData->HandleTable[Index].Object) == NULL) @@ -781,6 +783,9 @@ CSR_API(SrvVerifyConsoleIoHandle) RtlEnterCriticalSection(&ProcessData->HandleTableLock); + // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) || + // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) ); + if (!IsConsoleHandle(ConsoleHandle) || Index >= ProcessData->HandleTableSize || ProcessData->HandleTable[Index].Object == NULL) @@ -816,6 +821,9 @@ CSR_API(SrvDuplicateHandle) RtlEnterCriticalSection(&ProcessData->HandleTableLock); + // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) || + // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) ); + if ( /** !IsConsoleHandle(ConsoleHandle) || **/ Index >= ProcessData->HandleTableSize || (Entry = &ProcessData->HandleTable[Index])->Object == NULL) From 4a0a6ca46ab9a34e86cae5299e9c79f1a7779c0f Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 6 Aug 2013 21:34:25 +0000 Subject: [PATCH 22/25] [CRT] * Annotate time_s.h. svn path=/trunk/; revision=59661 --- reactos/include/crt/sec_api/time_s.h | 123 +++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 16 deletions(-) diff --git a/reactos/include/crt/sec_api/time_s.h b/reactos/include/crt/sec_api/time_s.h index fdcf1a848b8..5421831262a 100644 --- a/reactos/include/crt/sec_api/time_s.h +++ b/reactos/include/crt/sec_api/time_s.h @@ -3,6 +3,7 @@ * This file is part of the w64 mingw-runtime package. * No warranty is given; refer to the file DISCLAIMER within this package. */ + #ifndef _TIME_H__S #define _TIME_H__S @@ -14,22 +15,110 @@ extern "C" { #endif - _CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _strdate_s(char *_Buf,size_t _SizeInBytes); - _CRTIMP errno_t __cdecl _strtime_s(char *_Buf ,size_t _SizeInBytes); - _CRTIMP errno_t __cdecl _ctime64_s(char *_Buf,size_t _SizeInBytes,const __time64_t *_Time); - _CRTIMP errno_t __cdecl _gmtime64_s(struct tm *_Tm,const __time64_t *_Time); - _CRTIMP errno_t __cdecl _localtime64_s(struct tm *_Tm,const __time64_t *_Time); + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _ctime32_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf, + _In_ size_t _SizeInBytes, + _In_ const __time32_t *_Time); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _gmtime32_s( + _In_ struct tm *_Tm, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _localtime32_s( + _Out_ struct tm *_Tm, + _In_ const __time32_t *_Time); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _strdate_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf, + _In_range_(>= , 9) size_t _SizeInBytes); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _strtime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf, + _In_range_(>= , 9) size_t _SizeInBytes); + + _CRTIMP + errno_t + __cdecl + _ctime64_s( + _Out_writes_z_(_SizeInBytes) char *_Buf, + _In_ size_t _SizeInBytes, + _In_ const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _gmtime64_s( + _Out_ struct tm *_Tm, + _In_ const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _localtime64_s( + _Out_ struct tm *_Tm, + _In_ const __time64_t *_Time); #ifndef _WTIME_S_DEFINED #define _WTIME_S_DEFINED - _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wasctime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_range_(>= , 26) size_t _SizeInWords, + _In_ const struct tm *_Tm); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _wctime32_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wstrdate_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_ size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wstrtime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_range_(>= , 9) size_t _SizeInWords); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _wctime64_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time64_t *_Time); #if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) #define _INC_WTIME_S_INL @@ -38,7 +127,8 @@ extern "C" { __CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); } #endif #endif -#endif + +#endif /* _WTIME_S_DEFINED */ #ifndef RC_INVOKED #ifdef _USE_32BIT_TIME_T @@ -52,5 +142,6 @@ __CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { r } #endif -#endif -#endif +#endif /* MINGW_HAS_SECURE_API */ + +#endif /* _TIME_H__S */ From d6308efe55a4ebe8db60683550fec0f9456cdb2d Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 7 Aug 2013 12:28:47 +0000 Subject: [PATCH 23/25] [CMAKE] * We no longer need to maintain a transitional compatibility with the old CMake/RosBE for MSVC builds. svn path=/trunk/; revision=59663 --- reactos/cmake/Platform/Windows-cl.cmake | 307 ------------------------ 1 file changed, 307 deletions(-) delete mode 100644 reactos/cmake/Platform/Windows-cl.cmake diff --git a/reactos/cmake/Platform/Windows-cl.cmake b/reactos/cmake/Platform/Windows-cl.cmake deleted file mode 100644 index afd36b8542d..00000000000 --- a/reactos/cmake/Platform/Windows-cl.cmake +++ /dev/null @@ -1,307 +0,0 @@ -# try to load any previously computed information for C on this platform -INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake OPTIONAL) -# try to load any previously computed information for CXX on this platform -INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake OPTIONAL) - -SET(WIN32 1) - -INCLUDE(Platform/cl) - -############ -# Detect WDK build environment -IF($ENV{DDKBUILDENV} MATCHES "chk") - MESSAGE(STATUS "DDK/WDK checked build environment detected.") - SET(CMAKE_USE_WDK_ENV 1) -ENDIF() - -IF($ENV{DDKBUILDENV} MATCHES "fre") - MESSAGE(STATUS "DDK/WDK free build environment detected.") - SET(CMAKE_USE_WDK_ENV 1) -ENDIF() - -if(CMAKE_USE_WDK_ENV) - - # Detect output architecture - if(NOT ARCH) - if($ENV{AMD64} MATCHES 1) - set(ARCH amd64) - set(MSVC_C_ARCHITECTURE_ID 64) - else() - set(ARCH i386) - endif() - endif() - - # Force C/C++ Compilers - include(CMakeForceCompiler) - CMAKE_FORCE_C_COMPILER(cl MSVC) - CMAKE_FORCE_CXX_COMPILER(cl MSVC) - - # Add library directories - STRING(REPLACE * ${ARCH} ATL_LIB_PATH $ENV{ATL_LIB_PATH}) - STRING(REPLACE * ${ARCH} CRT_LIB_PATH $ENV{CRT_LIB_PATH}) - STRING(REPLACE * ${ARCH} DDK_LIB_PATH $ENV{DDK_LIB_PATH}) - STRING(REPLACE * ${ARCH} KMDF_LIB_PATH $ENV{KMDF_LIB_PATH}) - STRING(REPLACE * ${ARCH} MFC_LIB_PATH $ENV{MFC_LIB_PATH}) - STRING(REPLACE * ${ARCH} SDK_LIB_PATH $ENV{SDK_LIB_PATH}) - LINK_DIRECTORIES(${ATL_LIB_PATH} - ${CRT_LIB_PATH} - ${DDK_LIB_PATH} - ${IFSKIT_LIB_PATH} - ${KMDF_LIB_PATH} - ${MFC_LIB_PATH} - ${SDK_LIB_PATH}) - - # Add environment variables - if(NOT CMAKE_CROSSCOMPILING) - set(ENV{INCLUDE} "$ENV{CRT_INC_PATH};$ENV{SDK_INC_PATH};$ENV{SDK_INC_PATH}\\crt\\stl60") - include_directories($ENV{INCLUDE}) - set(ENV{LIBPATH} "${CRT_LIB_PATH};${SDK_LIB_PATH}") - set(ENV{USE_MSVCRT} 1) - set(ENV{USE_STL} 1) - set(ENV{STL_VER} 60) - endif() -endif() - -############ - -# Set lib path for ARM compiler -if(${ARCH} MATCHES arm) - message("Using ARM build for cross compilation. Host tools are x86.") - - # Force C/C++ Compilers - include(CMakeForceCompiler) - CMAKE_FORCE_C_COMPILER(cl MSVC) - CMAKE_FORCE_CXX_COMPILER(cl MSVC) - - if(NOT CMAKE_CROSSCOMPILING) - message("Using x86 target for ARM host tools.") - set(ARCH i386) - - LINK_DIRECTORIES($ENV{WindowsSdkDir}\\Lib\\win8\\um\\x86) - endif() - - #LINK_DIRECTORIES($ENV{LIB}) -endif() - - -############ - -SET(CMAKE_CREATE_WIN32_EXE /subsystem:windows) -SET(CMAKE_CREATE_CONSOLE_EXE /subsystem:console) - -IF(CMAKE_GENERATOR MATCHES "Visual Studio 6") - SET (CMAKE_NO_BUILD_TYPE 1) -ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 6") -IF(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio") - SET (CMAKE_NO_BUILD_TYPE 1) - SET (CMAKE_CONFIGURATION_TYPES "Debug;Release;MinSizeRel;RelWithDebInfo" CACHE STRING - "Semicolon separated list of supported configuration types, only supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything else will be ignored.") - MARK_AS_ADVANCED(CMAKE_CONFIGURATION_TYPES) -ENDIF(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio") -# does the compiler support pdbtype and is it the newer compiler -IF(CMAKE_GENERATOR MATCHES "Visual Studio 8") - SET(CMAKE_COMPILER_2005 1) -ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8") - -# make sure to enable languages after setting configuration types -ENABLE_LANGUAGE(RC) -SET(CMAKE_COMPILE_RESOURCE "rc /fo ") - -# for nmake we need to compute some information about the compiler -# that is being used. -# the compiler may be free command line, 6, 7, or 71, and -# each have properties that must be determined. -# to avoid running these tests with each cmake run, the -# test results are saved in CMakeCPlatform.cmake, a file -# that is automatically copied into try_compile directories -# by the global generator. -SET(MSVC_IDE 1) -IF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") - SET(MSVC_IDE 0) - IF(NOT CMAKE_VC_COMPILER_TESTS_RUN) - SET(CMAKE_VC_COMPILER_TESTS 1) - SET(testNmakeCLVersionFile - "${CMAKE_ROOT}/Modules/CMakeTestNMakeCLVersion.c") - STRING(REGEX REPLACE "/" "\\\\" testNmakeCLVersionFile "${testNmakeCLVersionFile}") - MESSAGE(STATUS "Check for CL compiler version") - SET(CMAKE_TEST_COMPILER ${CMAKE_C_COMPILER}) - IF (NOT CMAKE_C_COMPILER) - SET(CMAKE_TEST_COMPILER ${CMAKE_CXX_COMPILER}) - ENDIF(NOT CMAKE_C_COMPILER) - EXEC_PROGRAM(${CMAKE_TEST_COMPILER} - ARGS /nologo -EP \"${testNmakeCLVersionFile}\" - OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT - RETURN_VALUE CMAKE_COMPILER_RETURN - ) - IF(NOT CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining the version of compiler passed with the following output:\n" - "${CMAKE_COMPILER_OUTPUT}\n\n") - STRING(REGEX REPLACE "\n" " " compilerVersion "${CMAKE_COMPILER_OUTPUT}") - STRING(REGEX REPLACE ".*VERSION=(.*)" "\\1" - compilerVersion "${compilerVersion}") - MESSAGE(STATUS "Check for CL compiler version - ${compilerVersion}") - SET(MSVC60) - SET(MSVC70) - SET(MSVC71) - SET(MSVC80) - SET(CMAKE_COMPILER_2005) - IF("${compilerVersion}" LESS 1300) - SET(MSVC60 1) - SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 1) - ENDIF("${compilerVersion}" LESS 1300) - IF("${compilerVersion}" EQUAL 1300) - SET(MSVC70 1) - SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 0) - ENDIF("${compilerVersion}" EQUAL 1300) - IF("${compilerVersion}" EQUAL 1310) - SET(MSVC71 1) - SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 0) - ENDIF("${compilerVersion}" EQUAL 1310) - IF("${compilerVersion}" EQUAL 1400) - SET(MSVC80 1) - SET(CMAKE_COMPILER_2005 1) - ENDIF("${compilerVersion}" EQUAL 1400) - IF("${compilerVersion}" EQUAL 1500) - SET(MSVC90 1) - ENDIF("${compilerVersion}" EQUAL 1500) - IF("${compilerVersion}" EQUAL 1600) - SET(MSVC10 1) - ENDIF("${compilerVersion}" EQUAL 1600) - SET(MSVC_VERSION "${compilerVersion}") - ELSE(NOT CMAKE_COMPILER_RETURN) - MESSAGE(STATUS "Check for CL compiler version - failed") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining the version of compiler failed with the following output:\n" - "${CMAKE_COMPILER_OUTPUT}\n\n") - ENDIF(NOT CMAKE_COMPILER_RETURN) - # try to figure out if we are running the free command line - # tools from Microsoft. These tools do not provide debug libraries, - # so the link flags used have to be different. - MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2") - SET(testForFreeVCFile - "${CMAKE_ROOT}/Modules/CMakeTestForFreeVC.cxx") - STRING(REGEX REPLACE "/" "\\\\" testForFreeVCFile "${testForFreeVCFile}") - MESSAGE(STATUS "Check if this is a free VC compiler") - EXEC_PROGRAM(${CMAKE_TEST_COMPILER} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2 - ARGS /nologo /EHsc - \"${testForFreeVCFile}\" - OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT - RETURN_VALUE CMAKE_COMPILER_RETURN - ) - IF(CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if this is a free VC compiler failed with the following output:\n" - "${CMAKE_COMPILER_OUTPUT}\n\n") - MESSAGE(STATUS "Check if this is a free VC compiler - yes") - SET(CMAKE_USING_VC_FREE_TOOLS 1) - ELSE(CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if this is a free VC compiler passed with the following output:\n" - "${CMAKE_COMPILER_OUTPUT}\n\n") - MESSAGE(STATUS "Check if this is a free VC compiler - no") - SET(CMAKE_USING_VC_FREE_TOOLS 0) - ENDIF(CMAKE_COMPILER_RETURN) - MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp3") - ENDIF(NOT CMAKE_VC_COMPILER_TESTS_RUN) -ENDIF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") - -IF(MSVC_C_ARCHITECTURE_ID MATCHES 64) - SET(CMAKE_CL_64 1) -ELSE(MSVC_C_ARCHITECTURE_ID MATCHES 64) - SET(CMAKE_CL_64 0) -ENDIF(MSVC_C_ARCHITECTURE_ID MATCHES 64) -IF(CMAKE_FORCE_WIN64 OR CMAKE_FORCE_IA64) - SET(CMAKE_CL_64 1) -ENDIF(CMAKE_FORCE_WIN64 OR CMAKE_FORCE_IA64) - -IF("${MSVC_VERSION}" GREATER 1599) - SET(MSVC_INCREMENTAL_DEFAULT ON) -ENDIF() - -# No support for old versions -if(MSVC_VERSION LESS 1310) -message(FATAL_ERROR "Your compiler is too old. Get a newer version!") -endif() - -# for 2005 make sure the manifest is put in the dll with mt -#SET(CMAKE_CXX_CREATE_SHARED_LIBRARY " -E vs_link_dll ${CMAKE_CXX_CREATE_SHARED_LIBRARY}") -#SET(CMAKE_CXX_CREATE_SHARED_MODULE " -E vs_link_dll ${CMAKE_CXX_CREATE_SHARED_MODULE}") -# create a C shared library -#SET(CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}") -# create a C shared module just copy the shared library rule -#SET(CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE}") -#SET(CMAKE_CXX_LINK_EXECUTABLE " -E vs_link_exe ${CMAKE_CXX_LINK_EXECUTABLE}") -#SET(CMAKE_C_LINK_EXECUTABLE " -E vs_link_exe ${CMAKE_C_LINK_EXECUTABLE}") - -SET(CMAKE_BUILD_TYPE_INIT Debug) -SET(CMAKE_CXX_FLAGS_DEBUG_INIT "") -SET(CMAKE_C_FLAGS_DEBUG_INIT "") -SET(CMAKE_CXX_FLAGS_INIT "") -SET(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/O1 /Ob1 /D NDEBUG") -SET(CMAKE_CXX_FLAGS_RELEASE_INIT "") -SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/Zi /O2 /Ob1") -SET(CMAKE_C_FLAGS_INIT "") -SET(CMAKE_C_FLAGS_MINSIZEREL_INIT "/O1 /Ob1 /D NDEBUG") -SET(CMAKE_C_FLAGS_RELEASE_INIT "") -SET(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/Zi /O2 /Ob1") -SET(CMAKE_C_STANDARD_LIBRARIES_INIT "") -SET(CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT}") -SET(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") - -# executable linker flags -SET (CMAKE_LINK_DEF_FILE_FLAG "/DEF:") -# set the stack size and the machine type -SET(_MACHINE_ARCH_FLAG ${MSVC_C_ARCHITECTURE_ID}) -IF(NOT _MACHINE_ARCH_FLAG) - SET(_MACHINE_ARCH_FLAG ${MSVC_CXX_ARCHITECTURE_ID}) -ENDIF(NOT _MACHINE_ARCH_FLAG) -# HACK -if(${ARCH} MATCHES arm) - SET(_MACHINE_ARCH_FLAG ARM) -endif() -SET (CMAKE_EXE_LINKER_FLAGS_INIT - "${CMAKE_EXE_LINKER_FLAGS_INIT} /STACK:10000000 /machine:${_MACHINE_ARCH_FLAG}") - -# add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype -# on versions that support it -SET( MSVC_INCREMENTAL_YES_FLAG "") -IF(NOT MSVC_INCREMENTAL_DEFAULT) - SET( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:YES") -ENDIF() - -IF (CMAKE_COMPILER_SUPPORTS_PDBTYPE) - SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug /pdbtype:sept ${MSVC_INCREMENTAL_YES_FLAG}") - SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug /pdbtype:sept ${MSVC_INCREMENTAL_YES_FLAG}") -ELSE (CMAKE_COMPILER_SUPPORTS_PDBTYPE) - SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug ${MSVC_INCREMENTAL_YES_FLAG}") - SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug ${MSVC_INCREMENTAL_YES_FLAG}") -ENDIF (CMAKE_COMPILER_SUPPORTS_PDBTYPE) -# for release and minsize release default to no incremental linking -SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT "/INCREMENTAL:NO") -SET(CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT "/INCREMENTAL:NO") - -# copy the EXE_LINKER flags to SHARED and MODULE linker flags -# shared linker flags -SET (CMAKE_SHARED_LINKER_FLAGS_INIT ${CMAKE_EXE_LINKER_FLAGS_INIT}) -SET (CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT}) -SET (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT}) -SET (CMAKE_SHARED_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT}) -SET (CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT}) -# module linker flags -SET (CMAKE_MODULE_LINKER_FLAGS_INIT ${CMAKE_SHARED_LINKER_FLAGS_INIT}) -SET (CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT}) -SET (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT}) -SET (CMAKE_MODULE_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT}) -SET (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT}) - -# save computed information for this platform -IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake") - CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCPlatform.cmake IMMEDIATE) -ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake") - -IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake") - CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXPlatform.cmake IMMEDIATE) -ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake") From b8f23684cc95a739692a3060745fc62045f18761 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 7 Aug 2013 13:20:13 +0000 Subject: [PATCH 24/25] [CRT] * Annotate wchar_s.h. svn path=/trunk/; revision=59664 --- reactos/include/crt/sec_api/wchar_s.h | 737 +++++++++++++++++++++++--- 1 file changed, 658 insertions(+), 79 deletions(-) diff --git a/reactos/include/crt/sec_api/wchar_s.h b/reactos/include/crt/sec_api/wchar_s.h index 5ce967b7cab..9788be57359 100644 --- a/reactos/include/crt/sec_api/wchar_s.h +++ b/reactos/include/crt/sec_api/wchar_s.h @@ -3,6 +3,7 @@ * This file is part of the w64 mingw-runtime package. * No warranty is given; refer to the file DISCLAIMER within this package. */ + #ifndef _INC_WCHAR_S #define _INC_WCHAR_S @@ -16,100 +17,648 @@ extern "C" { #ifndef _WIO_S_DEFINED #define _WIO_S_DEFINED - _CRTIMP errno_t __cdecl _waccess_s(const wchar_t *_Filename,int _AccessMode); - _CRTIMP errno_t __cdecl _wmktemp_s(wchar_t *_TemplateName,size_t _SizeInWords); -#endif + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _waccess_s( + _In_z_ const wchar_t *_Filename, + _In_ int _AccessMode); + + _CRTIMP + errno_t + __cdecl + _wmktemp_s( + _Inout_updates_z_(_SizeInWords) wchar_t *_TemplateName, + _In_ size_t _SizeInWords); + +#endif /* _WIO_S_DEFINED */ #ifndef _WCONIO_S_DEFINED #define _WCONIO_S_DEFINED - _CRTIMP errno_t __cdecl _cgetws_s(wchar_t *_Buffer,size_t _SizeInWords,size_t *_SizeRead); - _CRTIMP int __cdecl _cwprintf_s(const wchar_t *_Format,...); - _CRTIMP int __cdecl _cwscanf_s(const wchar_t *_Format,...); - _CRTIMP int __cdecl _cwscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vcwprintf_s(const wchar_t *_Format,va_list _ArgList); - _CRTIMP int __cdecl _cwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vcwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); -#endif + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _cgetws_s( + _Out_writes_to_(_SizeInWords, *_SizeRead) wchar_t *_Buffer, + _In_ size_t _SizeInWords, + _Out_ size_t *_SizeRead); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _cwprintf_s( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _cwscanf_s( + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _cwscanf_s_l( + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vcwprintf_s( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + _CRTIMP + int + __cdecl + _cwprintf_s_l( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _CRTIMP + int + __cdecl + _vcwprintf_s_l( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + +#endif /* _WCONIO_S_DEFINED */ #ifndef _WSTDIO_S_DEFINED #define _WSTDIO_S_DEFINED - _CRTIMP wchar_t *__cdecl _getws_s(wchar_t *_Str,size_t _SizeInWords); - int __cdecl fwprintf_s(FILE *_File,const wchar_t *_Format,...); - int __cdecl wprintf_s(const wchar_t *_Format,...); - int __cdecl vfwprintf_s(FILE *_File,const wchar_t *_Format,va_list _ArgList); - int __cdecl vwprintf_s(const wchar_t *_Format,va_list _ArgList); - int __cdecl swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...); - int __cdecl vswprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList); - _CRTIMP int __cdecl _snwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,...); - _CRTIMP int __cdecl _vsnwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList); - _CRTIMP int __cdecl _wprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); - _CRTIMP int __cdecl _fwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vfwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); - _CRTIMP int __cdecl _swprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vswprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); - _CRTIMP int __cdecl _snwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vsnwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); - _CRTIMP int __cdecl _fwscanf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _swscanf_s_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _snwscanf_s(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...); - _CRTIMP int __cdecl _snwscanf_s_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _wscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP errno_t __cdecl _wfopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode); - _CRTIMP errno_t __cdecl _wfreopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile); - _CRTIMP errno_t __cdecl _wtmpnam_s(wchar_t *_DstBuf,size_t _SizeInWords); -#endif + + _Check_return_opt_ + _CRTIMP + wchar_t * + __cdecl + _getws_s( + _Out_writes_z_(_SizeInWords) wchar_t *_Str, + _In_ size_t _SizeInWords); + + _Check_return_opt_ + int + __cdecl + fwprintf_s( + _Inout_ FILE *_File, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + int + __cdecl + wprintf_s( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + int + __cdecl + vfwprintf_s( + _Inout_ FILE *_File, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + _Check_return_opt_ + int + __cdecl + vwprintf_s( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + int + __cdecl + swprintf_s( + _Out_writes_z_(_SizeInWords) wchar_t *_Dst, + _In_ size_t _SizeInWords, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + int + __cdecl + vswprintf_s( + _Out_writes_z_(_SizeInWords) wchar_t *_Dst, + _In_ size_t _SizeInWords, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _snwprintf_s( + _Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf, + _In_ size_t _DstSizeInWords, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vsnwprintf_s( + _Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf, + _In_ size_t _DstSizeInWords, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _wprintf_s_l( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vwprintf_s_l( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _fwprintf_s_l( + _Inout_ FILE *_File, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vfwprintf_s_l( + _Inout_ FILE *_File, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _swprintf_s_l( + _Out_writes_z_(_DstSize) wchar_t *_DstBuf, + _In_ size_t _DstSize, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vswprintf_s_l( + _Out_writes_z_(_DstSize) wchar_t *_DstBuf, + _In_ size_t _DstSize, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _snwprintf_s_l( + _Out_writes_z_(_DstSize) wchar_t *_DstBuf, + _In_ size_t _DstSize, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vsnwprintf_s_l( + _Out_writes_z_(_DstSize) wchar_t *_DstBuf, + _In_ size_t _DstSize, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _fwscanf_s_l( + _Inout_ FILE *_File, + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _swscanf_s_l( + _In_z_ const wchar_t *_Src, + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _snwscanf_s( + _In_reads_(_MaxCount) _Pre_z_ const wchar_t *_Src, + _In_ size_t _MaxCount, + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _snwscanf_s_l( + _In_reads_(_MaxCount) _Pre_z_ const wchar_t *_Src, + _In_ size_t _MaxCount, + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _wscanf_s_l( + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wfopen_s( + _Outptr_result_maybenull_ FILE **_File, + _In_z_ const wchar_t *_Filename, + _In_z_ const wchar_t *_Mode); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wfreopen_s( + _Outptr_result_maybenull_ FILE **_File, + _In_z_ const wchar_t *_Filename, + _In_z_ const wchar_t *_Mode, + _Inout_ FILE *_OldFile); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wtmpnam_s( + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords); + +#endif /* _WSTDIO_S_DEFINED */ #ifndef _WSTDLIB_S_DEFINED #define _WSTDLIB_S_DEFINED - _CRTIMP errno_t __cdecl _itow_s (int _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); - _CRTIMP errno_t __cdecl _ltow_s (long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); - _CRTIMP errno_t __cdecl _ultow_s (unsigned long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); - _CRTIMP errno_t __cdecl _wgetenv_s(size_t *_ReturnSize,wchar_t *_DstBuf,size_t _DstSizeInWords,const wchar_t *_VarName); - _CRTIMP errno_t __cdecl _wdupenv_s(wchar_t **_Buffer,size_t *_BufferSizeInWords,const wchar_t *_VarName); - _CRTIMP errno_t __cdecl _i64tow_s(__int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); - _CRTIMP errno_t __cdecl _ui64tow_s(unsigned __int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); -#endif + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _itow_s( + _In_ int _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _ltow_s( + _In_ long _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _ultow_s( + _In_ unsigned long _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wgetenv_s( + _Out_ size_t *_ReturnSize, + _Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf, + _In_ size_t _DstSizeInWords, + _In_z_ const wchar_t *_VarName); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wdupenv_s( + _Outptr_result_buffer_maybenull_(*_BufferSizeInWords) _Deref_post_z_ wchar_t **_Buffer, + _Out_opt_ size_t *_BufferSizeInWords, + _In_z_ const wchar_t *_VarName); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _i64tow_s( + _In_ __int64 _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _ui64tow_s( + _In_ unsigned __int64 _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + +#endif /* _WSTDLIB_S_DEFINED */ #ifndef _POSIX_ #ifndef _WSTDLIBP_S_DEFINED #define _WSTDLIBP_S_DEFINED - _CRTIMP errno_t __cdecl _wmakepath_s(wchar_t *_PathResult,size_t _SizeInWords,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext); - _CRTIMP errno_t __cdecl _wputenv_s(const wchar_t *_Name,const wchar_t *_Value); - _CRTIMP errno_t __cdecl _wsearchenv_s(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wsplitpath_s(const wchar_t *_FullPath,wchar_t *_Drive,size_t _DriveSizeInWords,wchar_t *_Dir,size_t _DirSizeInWords,wchar_t *_Filename,size_t _FilenameSizeInWords,wchar_t *_Ext,size_t _ExtSizeInWords); -#endif -#endif + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wmakepath_s( + _Out_writes_z_(_SizeInBytes) wchar_t *_PathResult, + _In_ size_t _SizeInWords, + _In_opt_z_ const wchar_t *_Drive, + _In_opt_z_ const wchar_t *_Dir, + _In_opt_z_ const wchar_t *_Filename, + _In_opt_z_ const wchar_t *_Ext); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wputenv_s( + _In_z_ const wchar_t *_Name, + _In_z_ const wchar_t *_Value); + + _CRTIMP + errno_t + __cdecl + _wsearchenv_s( + _In_z_ const wchar_t *_Filename, + _In_z_ const wchar_t *_EnvVar, + _Out_writes_z_(_SizeInWords) wchar_t *_ResultPath, + _In_ size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wsplitpath_s( + _In_z_ const wchar_t *_FullPath, + _Out_writes_opt_z_(_DriveSizeInWords) wchar_t *_Drive, + _In_ size_t _DriveSizeInWords, + _Out_writes_opt_z_(_DirSizeInWords) wchar_t *_Dir, + _In_ size_t _DirSizeInWords, + _Out_writes_opt_z_(_FilenameSizeInWords) wchar_t *_Filename, + _In_ size_t _FilenameSizeInWords, + _Out_writes_opt_z_(_ExtSizeInWords) wchar_t *_Ext, + _In_ size_t _ExtSizeInWords); + +#endif /* _WSTDLIBP_S_DEFINED */ +#endif /* _POSIX_ */ #ifndef _WSTRING_S_DEFINED #define _WSTRING_S_DEFINED - _CRTIMP wchar_t *__cdecl wcstok_s(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context); - _CRTIMP errno_t __cdecl _wcserror_s(wchar_t *_Buf,size_t _SizeInWords,int _ErrNum); - _CRTIMP errno_t __cdecl __wcserror_s(wchar_t *_Buffer,size_t _SizeInWords,const wchar_t *_ErrMsg); - _CRTIMP errno_t __cdecl _wcsnset_s(wchar_t *_Dst,size_t _DstSizeInWords,wchar_t _Val,size_t _MaxCount); - _CRTIMP errno_t __cdecl _wcsset_s(wchar_t *_Str,size_t _SizeInWords,wchar_t _Val); - _CRTIMP errno_t __cdecl _wcslwr_s(wchar_t *_Str,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wcslwr_s_l(wchar_t *_Str,size_t _SizeInWords,_locale_t _Locale); - _CRTIMP errno_t __cdecl _wcsupr_s(wchar_t *_Str,size_t _Size); - _CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale); - _CRTIMP errno_t __cdecl wcsncat_s(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount); - _CRTIMP errno_t __cdecl _wcsncat_s_l(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale); - _CRTIMP errno_t __cdecl wcsncpy_s(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount); - _CRTIMP errno_t __cdecl _wcsncpy_s_l(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale); - _CRTIMP wchar_t *__cdecl _wcstok_s_l(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context,_locale_t _Locale); - _CRTIMP errno_t __cdecl _wcsset_s_l(wchar_t *_Str,size_t _SizeInChars,unsigned int _Val,_locale_t _Locale); - _CRTIMP errno_t __cdecl _wcsnset_s_l(wchar_t *_Str,size_t _SizeInChars,unsigned int _Val, size_t _Count,_locale_t _Locale); + _Check_return_ + _CRTIMP + wchar_t * + __cdecl + wcstok_s( + _Inout_opt_z_ wchar_t *_Str, + _In_z_ const wchar_t *_Delim, + _Inout_ _Deref_prepost_opt_z_ wchar_t **_Context); -#endif + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcserror_s( + _Out_writes_opt_z_(_SizeInWords) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ int _ErrNum); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + __wcserror_s( + _Out_writes_opt_z_(_SizeInWords) wchar_t *_Buffer, + _In_ size_t _SizeInWords, + _In_z_ const wchar_t *_ErrMsg); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsnset_s( + _Inout_updates_z_(_DstSizeInWords) wchar_t *_Dst, + _In_ size_t _DstSizeInWords, + wchar_t _Val, + _In_ size_t _MaxCount); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsset_s( + _Inout_updates_z_(_SizeInWords) wchar_t *_Str, + _In_ size_t _SizeInWords, + wchar_t _Val); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcslwr_s( + _Inout_updates_z_(_SizeInWords) wchar_t *_Str, + _In_ size_t _SizeInWords); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcslwr_s_l( + _Inout_updates_z_(_SizeInWords) wchar_t *_Str, + _In_ size_t _SizeInWords, + _In_opt_ _locale_t _Locale); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsupr_s( + _Inout_updates_z_(_Size) wchar_t *_Str, + _In_ size_t _Size); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsupr_s_l( + _Inout_updates_z_(_Size) wchar_t *_Str, + _In_ size_t _Size, + _In_opt_ _locale_t _Locale); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + wcsncat_s( + _Inout_updates_z_(_DstSizeInChars) wchar_t *_Dst, + _In_ size_t _DstSizeInChars, + _In_z_ const wchar_t *_Src, + _In_ size_t _MaxCount); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsncat_s_l( + _Inout_updates_z_(_DstSizeInChars) wchar_t *_Dst, + _In_ size_t _DstSizeInChars, + _In_z_ const wchar_t *_Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + wcsncpy_s( + _Out_writes_z_(_DstSizeInChars) wchar_t *_Dst, + _In_ size_t _DstSizeInChars, + _In_z_ const wchar_t *_Src, + _In_ size_t _MaxCount); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsncpy_s_l( + _Out_writes_z_(_DstSizeInChars) wchar_t *_Dst, + _In_ size_t _DstSizeInChars, + _In_z_ const wchar_t *_Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _CRTIMP + wchar_t * + __cdecl + _wcstok_s_l( + wchar_t *_Str, + const wchar_t *_Delim, + wchar_t **_Context, + _locale_t _Locale); + + _CRTIMP + errno_t + __cdecl + _wcsset_s_l( + wchar_t *_Str, + size_t _SizeInChars, + unsigned int _Val, + _locale_t _Locale); + + _CRTIMP + errno_t + __cdecl + _wcsnset_s_l( + wchar_t *_Str, + size_t _SizeInChars, + unsigned int _Val, + size_t _Count, + _locale_t _Locale); + +#endif /* _WSTRING_S_DEFINED */ #ifndef _WTIME_S_DEFINED #define _WTIME_S_DEFINED - _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wasctime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const struct tm *_Tm); + + _CRTIMP + errno_t + __cdecl + _wctime32_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wstrdate_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_range_(>= , 9) size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wstrtime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_ size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wctime64_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time64_t *_Time); #if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) #define _INC_WTIME_S_INL @@ -117,16 +666,46 @@ extern "C" { #ifndef _USE_32BIT_TIME_T __CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); } #endif -#endif #endif - _CRTIMP errno_t __cdecl mbsrtowcs_s(size_t *_Retval,wchar_t *_Dst,size_t _SizeInWords,const char **_PSrc,size_t _N,mbstate_t *_State); - _CRTIMP errno_t __cdecl wcrtomb_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,wchar_t _Ch,mbstate_t *_State); - _CRTIMP errno_t __cdecl wcsrtombs_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,const wchar_t **_Src,size_t _Size,mbstate_t *_State); +#endif /* _WTIME_S_DEFINED */ + + _CRTIMP + errno_t + __cdecl + mbsrtowcs_s( + _Out_opt_ size_t *_Retval, + _Out_writes_opt_z_(_SizeInWords) wchar_t *_Dst, + _In_ size_t _SizeInWords, + _Inout_ _Deref_prepost_opt_valid_ const char **_PSrc, + _In_ size_t _N, + _Out_opt_ mbstate_t *_State); + + _CRTIMP + errno_t + __cdecl + wcrtomb_s( + _Out_opt_ size_t *_Retval, + _Out_writes_opt_z_(_SizeInBytes) char *_Dst, + _In_ size_t _SizeInBytes, + _In_ wchar_t _Ch, + _Out_opt_ mbstate_t *_State); + + _CRTIMP + errno_t + __cdecl + wcsrtombs_s( + _Out_opt_ size_t *_Retval, + _Out_writes_bytes_to_opt_(_SizeInBytes, *_Retval) char *_Dst, + _In_ size_t _SizeInBytes, + _Inout_ _Deref_prepost_z_ const wchar_t **_Src, + _In_ size_t _Size, + _Out_opt_ mbstate_t *_State); #ifdef __cplusplus } #endif -#endif -#endif +#endif /* MINGW_HAS_SECURE_API */ + +#endif /* _INC_WCHAR_S */ From 91d183762df4c491f22b5158bfeee9882c952c2f Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 7 Aug 2013 21:03:03 +0000 Subject: [PATCH 25/25] [PSDK] * Annotate wininet.h. svn path=/trunk/; revision=59670 --- reactos/include/psdk/wininet.h | 1304 ++++++++++++++++++++++++++------ 1 file changed, 1074 insertions(+), 230 deletions(-) diff --git a/reactos/include/psdk/wininet.h b/reactos/include/psdk/wininet.h index 51d98643ba9..a70ce9d646f 100644 --- a/reactos/include/psdk/wininet.h +++ b/reactos/include/psdk/wininet.h @@ -24,7 +24,7 @@ extern "C" { #endif #define INTERNETAPI -#define BOOLAPI INTERNETAPI BOOL WINAPI +#define BOOLAPI _Success_(return != 0) INTERNETAPI BOOL WINAPI typedef LPVOID HINTERNET; typedef HINTERNET * LPHINTERNET; @@ -387,32 +387,104 @@ typedef struct _INTERNET_DIAGNOSTIC_SOCKET_INFO #define IDSI_FLAG_PROXY 0x00000004 #define IDSI_FLAG_TUNNEL 0x00000008 -BOOLAPI InternetTimeFromSystemTimeA(CONST SYSTEMTIME *,DWORD ,LPSTR ,DWORD); -BOOLAPI InternetTimeFromSystemTimeW(CONST SYSTEMTIME *,DWORD ,LPWSTR ,DWORD); +BOOLAPI +InternetTimeFromSystemTimeA( + _In_ CONST SYSTEMTIME *pst, + _In_ DWORD dwRFC, + _Out_writes_bytes_(cbTime) LPSTR lpszTime, + _In_ DWORD cbTime); + +BOOLAPI +InternetTimeFromSystemTimeW( + _In_ CONST SYSTEMTIME *pst, + _In_ DWORD dwRFC, + _Out_writes_bytes_(cbTime) LPWSTR lpszTime, + _In_ DWORD cbTime); + #define InternetTimeFromSystemTime WINELIB_NAME_AW(InternetTimeFromSystemTime) #define INTERNET_RFC1123_FORMAT 0 #define INTERNET_RFC1123_BUFSIZE 30 -BOOLAPI InternetTimeToSystemTimeA(LPCSTR ,SYSTEMTIME *,DWORD); -BOOLAPI InternetTimeToSystemTimeW(LPCWSTR ,SYSTEMTIME *,DWORD); +BOOLAPI +InternetTimeToSystemTimeA( + _In_ LPCSTR, + _Out_ SYSTEMTIME *, + _Reserved_ DWORD); + +BOOLAPI +InternetTimeToSystemTimeW( + _In_ LPCWSTR, + _Out_ SYSTEMTIME *, + _Reserved_ DWORD); + #define InternetTimeToSystemTime WINELIB_NAME_AW(InternetTimeToSystemTime) -BOOLAPI InternetCrackUrlA(LPCSTR ,DWORD ,DWORD ,LPURL_COMPONENTSA); -BOOLAPI InternetCrackUrlW(LPCWSTR ,DWORD ,DWORD ,LPURL_COMPONENTSW); -#define InternetCrackUrl WINELIB_NAME_AW(InternetCrackUrl) +BOOLAPI +InternetCrackUrlA( + _In_reads_(dwUrlLength) LPCSTR lpszUrl, + _In_ DWORD dwUrlLength, + _In_ DWORD dwFlags, + _Inout_ LPURL_COMPONENTSA lpUrlComponents); + +BOOLAPI +InternetCrackUrlW( + _In_reads_(dwUrlLength) LPCWSTR lpszUrl, + _In_ DWORD dwUrlLength, + _In_ DWORD dwFlags, + _Inout_ LPURL_COMPONENTSW lpUrlComponents); + +#define InternetCrackUrl WINELIB_NAME_AW(InternetCrackUrl) + +BOOLAPI +InternetCreateUrlA( + _In_ LPURL_COMPONENTSA lpUrlComponents, + _In_ DWORD dwFlags, + _Out_writes_opt_(*lpdwUrlLength) LPSTR lpszUrl, + _Inout_ LPDWORD lpdwUrlLength); + +BOOLAPI +InternetCreateUrlW( + _In_ LPURL_COMPONENTSW lpUrlComponents, + _In_ DWORD dwFlags, + _Out_writes_opt_(*lpdwUrlLength) LPWSTR lpszUrl, + _Inout_ LPDWORD lpdwUrlLength); -BOOLAPI InternetCreateUrlA(LPURL_COMPONENTSA ,DWORD ,LPSTR ,LPDWORD); -BOOLAPI InternetCreateUrlW(LPURL_COMPONENTSW ,DWORD ,LPWSTR ,LPDWORD); #define InternetCreateUrl WINELIB_NAME_AW(InternetCreateUrl) -BOOLAPI InternetCanonicalizeUrlA(LPCSTR ,LPSTR ,LPDWORD ,DWORD); -BOOLAPI InternetCanonicalizeUrlW(LPCWSTR ,LPWSTR ,LPDWORD ,DWORD); -#define InternetCanonicalizeUrl WINELIB_NAME_AW(InternetCanonicalizeUrl) +BOOLAPI +InternetCanonicalizeUrlA( + _In_ LPCSTR lpszUrl, + _Out_writes_(*lpdwBufferLength) LPSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _In_ DWORD dwFlags); -BOOLAPI InternetCombineUrlA(LPCSTR ,LPCSTR ,LPSTR ,LPDWORD ,DWORD); -BOOLAPI InternetCombineUrlW(LPCWSTR ,LPCWSTR ,LPWSTR ,LPDWORD ,DWORD); -#define InternetCombineUrl WINELIB_NAME_AW(InternetCombineUrl) +BOOLAPI +InternetCanonicalizeUrlW( + _In_ LPCWSTR lpszUrl, + _Out_writes_(*lpdwBufferLength) LPWSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _In_ DWORD dwFlags); + +#define InternetCanonicalizeUrl WINELIB_NAME_AW(InternetCanonicalizeUrl) + +BOOLAPI +InternetCombineUrlA( + _In_ LPCSTR lpszBaseUrl, + _In_ LPCSTR lpszRelativeUrl, + _Out_writes_(*lpdwBufferLength) LPSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _In_ DWORD dwFlags); + +BOOLAPI +InternetCombineUrlW( + _In_ LPCWSTR lpszBaseUrl, + _In_ LPCWSTR lpszRelativeUrl, + _Out_writes_(*lpdwBufferLength) LPWSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _In_ DWORD dwFlags); + +#define InternetCombineUrl WINELIB_NAME_AW(InternetCombineUrl) #define ICU_ESCAPE 0x80000000 #define ICU_USERNAME 0x40000000 @@ -423,9 +495,27 @@ BOOLAPI InternetCombineUrlW(LPCWSTR ,LPCWSTR ,LPWSTR ,LPDWORD ,DWORD); #define ICU_BROWSER_MODE 0x02000000 #define ICU_ENCODE_PERCENT 0x00001000 -INTERNETAPI HINTERNET WINAPI InternetOpenA(LPCSTR ,DWORD ,LPCSTR ,LPCSTR ,DWORD); -INTERNETAPI HINTERNET WINAPI InternetOpenW(LPCWSTR ,DWORD ,LPCWSTR ,LPCWSTR ,DWORD); -#define InternetOpen WINELIB_NAME_AW(InternetOpen) +INTERNETAPI +HINTERNET +WINAPI +InternetOpenA( + _In_opt_ LPCSTR, + _In_ DWORD, + _In_opt_ LPCSTR, + _In_opt_ LPCSTR, + _In_ DWORD); + +INTERNETAPI +HINTERNET +WINAPI +InternetOpenW( + _In_opt_ LPCWSTR, + _In_ DWORD, + _In_opt_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ DWORD); + +#define InternetOpen WINELIB_NAME_AW(InternetOpen) #define INTERNET_OPEN_TYPE_PRECONFIG 0 #define INTERNET_OPEN_TYPE_DIRECT 1 @@ -435,13 +525,35 @@ INTERNETAPI HINTERNET WINAPI InternetOpenW(LPCWSTR ,DWORD ,LPCWSTR ,LPCWSTR ,DWO #define LOCAL_INTERNET_ACCESS INTERNET_OPEN_TYPE_DIRECT #define CERN_PROXY_INTERNET_ACCESS INTERNET_OPEN_TYPE_PROXY -BOOLAPI InternetCloseHandle(HINTERNET); +BOOLAPI InternetCloseHandle(_In_ HINTERNET); -INTERNETAPI HINTERNET WINAPI InternetConnectA(HINTERNET ,LPCSTR ,INTERNET_PORT , - LPCSTR ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR ); -INTERNETAPI HINTERNET WINAPI InternetConnectW(HINTERNET ,LPCWSTR ,INTERNET_PORT , - LPCWSTR ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR ); -#define InternetConnect WINELIB_NAME_AW(InternetConnect) +INTERNETAPI +HINTERNET +WINAPI +InternetConnectA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_ INTERNET_PORT, + _In_opt_ LPCSTR, + _In_opt_ LPCSTR, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +INTERNETAPI +HINTERNET +WINAPI +InternetConnectW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_ INTERNET_PORT, + _In_opt_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define InternetConnect WINELIB_NAME_AW(InternetConnect) #define INTERNET_SERVICE_URL 0 #define INTERNET_SERVICE_FTP 1 @@ -459,41 +571,126 @@ INTERNETAPI HINTERNET WINAPI InternetConnectW(HINTERNET ,LPCWSTR ,INTERNET_PORT dwContext \ ) -INTERNETAPI HINTERNET WINAPI InternetOpenUrlA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI InternetOpenUrlW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR); -#define InternetOpenUrl WINELIB_NAME_AW(InternetOpenUrl) +INTERNETAPI +HINTERNET +WINAPI +InternetOpenUrlA( + _In_ HINTERNET hInternet, + _In_ LPCSTR lpszUrl, + _In_reads_opt_(dwHeadersLength) LPCSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); -BOOLAPI InternetReadFile( HINTERNET ,LPVOID ,DWORD ,LPDWORD ); -INTERNETAPI BOOL WINAPI InternetReadFileExA( HINTERNET ,LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR ); -INTERNETAPI BOOL WINAPI InternetReadFileExW( HINTERNET ,LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR ); -#define InternetReadFileEx WINELIB_NAME_AW(InternetReadFileEx) +INTERNETAPI +HINTERNET +WINAPI +InternetOpenUrlW( + _In_ HINTERNET hInternet, + _In_ LPCWSTR lpszUrl, + _In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +#define InternetOpenUrl WINELIB_NAME_AW(InternetOpenUrl) + +BOOLAPI +InternetReadFile( + _In_ HINTERNET hFile, + _Out_writes_bytes_(dwNumberOfBytesToRead) __out_data_source(NETWORK) LPVOID lpBuffer, + _In_ DWORD dwNumberOfBytesToRead, + _Out_ LPDWORD lpdwNumberOfBytesRead); + +BOOLAPI +InternetReadFileExA( + _In_ HINTERNET hFile, + _Out_ __out_data_source(NETWORK) LPINTERNET_BUFFERSA lpBuffersOut, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +BOOLAPI +InternetReadFileExW( + _In_ HINTERNET hFile, + _Out_ __out_data_source(NETWORK) LPINTERNET_BUFFERSW lpBuffersOut, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +#define InternetReadFileEx WINELIB_NAME_AW(InternetReadFileEx) #define IRF_ASYNC WININET_API_FLAG_ASYNC #define IRF_SYNC WININET_API_FLAG_SYNC #define IRF_USE_CONTEXT WININET_API_FLAG_USE_CONTEXT #define IRF_NO_WAIT 0x00000008 -INTERNETAPI DWORD WINAPI InternetSetFilePointer(HINTERNET ,LONG ,PVOID ,DWORD ,DWORD_PTR); -BOOLAPI InternetWriteFile(HINTERNET ,LPCVOID ,DWORD ,LPDWORD); -BOOLAPI InternetQueryDataAvailable(HINTERNET ,LPDWORD ,DWORD ,DWORD_PTR); -BOOLAPI InternetFindNextFileA(HINTERNET ,LPVOID); -BOOLAPI InternetFindNextFileW(HINTERNET ,LPVOID); +INTERNETAPI +DWORD +WINAPI +InternetSetFilePointer( + _In_ HINTERNET, + _In_ LONG, + _Inout_opt_ PVOID, + _In_ DWORD, + _Reserved_ DWORD_PTR); + +BOOLAPI +InternetWriteFile( + _In_ HINTERNET hFile, + _In_reads_bytes_(dwNumberOfBytesToWrite) LPCVOID lpBuffer, + _In_ DWORD dwNumberOfBytesToWrite, + _Out_ LPDWORD lpdwNumberOfBytesWritten); + +BOOLAPI +InternetQueryDataAvailable( + _In_ HINTERNET hFile, + _Out_opt_ __out_data_source(NETWORK) LPDWORD lpdwNumberOfBytesAvailable, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +BOOLAPI InternetFindNextFileA(_In_ HINTERNET, _Out_ LPVOID); +BOOLAPI InternetFindNextFileW(_In_ HINTERNET, _Out_ LPVOID); #define InternetFindNextFile WINELIB_NAME_AW(InternetFindNextFile) -BOOLAPI InternetQueryOptionA(HINTERNET ,DWORD ,LPVOID ,LPDWORD); -BOOLAPI InternetQueryOptionW(HINTERNET ,DWORD ,LPVOID ,LPDWORD); -#define InternetQueryOption WINELIB_NAME_AW(InternetQueryOption) +BOOLAPI +InternetQueryOptionA( + _In_opt_ HINTERNET hInternet, + _In_ DWORD dwOption, + _Out_writes_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwBufferLength); -BOOLAPI InternetSetOptionA(HINTERNET ,DWORD ,LPVOID ,DWORD); -BOOLAPI InternetSetOptionW(HINTERNET ,DWORD ,LPVOID ,DWORD); +BOOLAPI +InternetQueryOptionW( + _In_opt_ HINTERNET hInternet, + _In_ DWORD dwOption, + _Out_writes_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwBufferLength); + +#define InternetQueryOption WINELIB_NAME_AW(InternetQueryOption) + +BOOLAPI InternetSetOptionA(_In_opt_ HINTERNET, _In_ DWORD, _In_opt_ LPVOID, _In_ DWORD); +BOOLAPI InternetSetOptionW(_In_opt_ HINTERNET, _In_ DWORD, _In_opt_ LPVOID, _In_ DWORD); #define InternetSetOption WINELIB_NAME_AW(InternetSetOption) -BOOLAPI InternetSetOptionExA(HINTERNET ,DWORD ,LPVOID ,DWORD ,DWORD); -BOOLAPI InternetSetOptionExW(HINTERNET ,DWORD ,LPVOID ,DWORD ,DWORD); -#define InternetSetOptionEx WINELIB_NAME_AW(InternetSetOptionEx) +BOOLAPI +InternetSetOptionExA( + _In_opt_ HINTERNET, + _In_ DWORD, + _In_opt_ LPVOID, + _In_ DWORD, + _In_ DWORD); -BOOLAPI InternetLockRequestFile(HINTERNET ,HANDLE *); -BOOLAPI InternetUnlockRequestFile(HANDLE); +BOOLAPI +InternetSetOptionExW( + _In_opt_ HINTERNET, + _In_ DWORD, + _In_opt_ LPVOID, + _In_ DWORD, + _In_ DWORD); + +#define InternetSetOptionEx WINELIB_NAME_AW(InternetSetOptionEx) + +BOOLAPI InternetLockRequestFile(_In_ HINTERNET, _Out_ HANDLE *); +BOOLAPI InternetUnlockRequestFile(_Inout_ HANDLE); #define ISO_GLOBAL 0x00000001 #define ISO_REGISTRY 0x00000002 @@ -643,17 +840,43 @@ BOOLAPI InternetUnlockRequestFile(HANDLE); -BOOLAPI InternetGetLastResponseInfoA(LPDWORD ,LPSTR ,LPDWORD); -BOOLAPI InternetGetLastResponseInfoW(LPDWORD ,LPWSTR ,LPDWORD); -#define InternetGetLastResponseInfo WINELIB_NAME_AW(InternetGetLastResponseInfo) +BOOLAPI +InternetGetLastResponseInfoA( + _Out_ LPDWORD lpdwError, + _Out_writes_opt_(*lpdwBufferLength) LPSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength); -typedef VOID (CALLBACK *INTERNET_STATUS_CALLBACK)(HINTERNET ,DWORD_PTR ,DWORD , - LPVOID ,DWORD); +BOOLAPI +InternetGetLastResponseInfoW( + _Out_ LPDWORD lpdwError, + _Out_writes_opt_(*lpdwBufferLength) LPWSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength); +#define InternetGetLastResponseInfo WINELIB_NAME_AW(InternetGetLastResponseInfo) + +typedef VOID +(CALLBACK *INTERNET_STATUS_CALLBACK)( + _In_ HINTERNET, + _In_opt_ DWORD_PTR, + _In_ DWORD, + _In_opt_ LPVOID, + _In_ DWORD); typedef INTERNET_STATUS_CALLBACK * LPINTERNET_STATUS_CALLBACK; -INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA(HINTERNET ,INTERNET_STATUS_CALLBACK); -INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(HINTERNET ,INTERNET_STATUS_CALLBACK); +INTERNETAPI +INTERNET_STATUS_CALLBACK +WINAPI +InternetSetStatusCallbackA( + _In_ HINTERNET, + _In_opt_ INTERNET_STATUS_CALLBACK); + +INTERNETAPI +INTERNET_STATUS_CALLBACK +WINAPI +InternetSetStatusCallbackW( + _In_ HINTERNET, + _In_opt_ INTERNET_STATUS_CALLBACK); + #define InternetSetStatusCallback WINELIB_NAME_AW(InternetSetStatusCallback) #define INTERNET_STATUS_RESOLVING_NAME 10 @@ -695,53 +918,145 @@ INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(HINTERNET #define FTP_TRANSFER_TYPE_BINARY 0x00000002 #define FTP_TRANSFER_TYPE_MASK (FTP_TRANSFER_TYPE_ASCII | FTP_TRANSFER_TYPE_BINARY) -BOOLAPI FtpCommandA(HINTERNET, BOOL, DWORD, LPCSTR, DWORD_PTR, HINTERNET *); -BOOLAPI FtpCommandW(HINTERNET, BOOL, DWORD, LPCWSTR, DWORD_PTR, HINTERNET *); -#define FtpCommand WINELIB_NAME_AW(FtpCommand) +BOOLAPI +FtpCommandA( + _In_ HINTERNET, + _In_ BOOL, + _In_ DWORD, + _In_ LPCSTR, + _In_opt_ DWORD_PTR, + _Out_opt_ HINTERNET *); -INTERNETAPI HINTERNET WINAPI FtpFindFirstFileA(HINTERNET ,LPCSTR , - LPWIN32_FIND_DATAA ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI FtpFindFirstFileW(HINTERNET ,LPCWSTR , - LPWIN32_FIND_DATAW ,DWORD ,DWORD_PTR); -#define FtpFindFirstFile WINELIB_NAME_AW(FtpFindFirstFile) +BOOLAPI +FtpCommandW( + _In_ HINTERNET, + _In_ BOOL, + _In_ DWORD, + _In_ LPCWSTR, + _In_opt_ DWORD_PTR, + _Out_opt_ HINTERNET *); -BOOLAPI FtpGetFileA(HINTERNET ,LPCSTR ,LPCSTR ,BOOL ,DWORD ,DWORD ,DWORD_PTR); -BOOLAPI FtpGetFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,BOOL ,DWORD ,DWORD ,DWORD_PTR); -#define FtpGetFile WINELIB_NAME_AW(FtpGetFile) +#define FtpCommand WINELIB_NAME_AW(FtpCommand) -DWORD WINAPI FtpGetFileSize(HINTERNET, LPDWORD); +INTERNETAPI +HINTERNET +WINAPI +FtpFindFirstFileA( + _In_ HINTERNET, + _In_opt_ LPCSTR, + _Out_opt_ LPWIN32_FIND_DATAA, + _In_ DWORD, + _In_opt_ DWORD_PTR); -BOOLAPI FtpPutFileA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD_PTR); -BOOLAPI FtpPutFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD_PTR); -#define FtpPutFile WINELIB_NAME_AW(FtpPutFile) +INTERNETAPI +HINTERNET +WINAPI +FtpFindFirstFileW( + _In_ HINTERNET, + _In_opt_ LPCWSTR, + _Out_opt_ LPWIN32_FIND_DATAW, + _In_ DWORD, + _In_opt_ DWORD_PTR); -BOOLAPI FtpDeleteFileA(HINTERNET ,LPCSTR); -BOOLAPI FtpDeleteFileW(HINTERNET ,LPCWSTR); +#define FtpFindFirstFile WINELIB_NAME_AW(FtpFindFirstFile) + +BOOLAPI +FtpGetFileA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_ LPCSTR, + _In_ BOOL, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +BOOLAPI +FtpGetFileW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_ LPCWSTR, + _In_ BOOL, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define FtpGetFile WINELIB_NAME_AW(FtpGetFile) + +DWORD WINAPI FtpGetFileSize(_In_ HINTERNET, _Out_opt_ LPDWORD); + +BOOLAPI +FtpPutFileA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_ LPCSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +BOOLAPI +FtpPutFileW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_ LPCWSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define FtpPutFile WINELIB_NAME_AW(FtpPutFile) + +BOOLAPI FtpDeleteFileA(_In_ HINTERNET, _In_ LPCSTR); +BOOLAPI FtpDeleteFileW(_In_ HINTERNET, _In_ LPCWSTR); #define FtpDeleteFile WINELIB_NAME_AW(FtpDeleteFile) -BOOLAPI FtpRenameFileA(HINTERNET ,LPCSTR ,LPCSTR); -BOOLAPI FtpRenameFileW(HINTERNET ,LPCWSTR ,LPCWSTR); +BOOLAPI FtpRenameFileA(_In_ HINTERNET, _In_ LPCSTR, _In_ LPCSTR); +BOOLAPI FtpRenameFileW(_In_ HINTERNET, _In_ LPCWSTR, _In_ LPCWSTR); #define FtpRenameFile WINELIB_NAME_AW(FtpRenameFile) -INTERNETAPI HINTERNET WINAPI FtpOpenFileA(HINTERNET ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI FtpOpenFileW(HINTERNET ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR); -#define FtpOpenFile WINELIB_NAME_AW(FtpOpenFile) +INTERNETAPI +HINTERNET +WINAPI +FtpOpenFileA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); -BOOLAPI FtpCreateDirectoryA(HINTERNET ,LPCSTR); -BOOLAPI FtpCreateDirectoryW(HINTERNET ,LPCWSTR); +INTERNETAPI +HINTERNET +WINAPI +FtpOpenFileW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define FtpOpenFile WINELIB_NAME_AW(FtpOpenFile) + +BOOLAPI FtpCreateDirectoryA(_In_ HINTERNET, _In_ LPCSTR); +BOOLAPI FtpCreateDirectoryW(_In_ HINTERNET, _In_ LPCWSTR); #define FtpCreateDirectory WINELIB_NAME_AW(FtpCreateDirectory) -BOOLAPI FtpRemoveDirectoryA(HINTERNET ,LPCSTR); -BOOLAPI FtpRemoveDirectoryW(HINTERNET ,LPCWSTR); +BOOLAPI FtpRemoveDirectoryA(_In_ HINTERNET, _In_ LPCSTR); +BOOLAPI FtpRemoveDirectoryW(_In_ HINTERNET, _In_ LPCWSTR); #define FtpRemoveDirectory WINELIB_NAME_AW(FtpRemoveDirectory) -BOOLAPI FtpSetCurrentDirectoryA(HINTERNET ,LPCSTR); -BOOLAPI FtpSetCurrentDirectoryW(HINTERNET ,LPCWSTR); +BOOLAPI FtpSetCurrentDirectoryA(_In_ HINTERNET, _In_ LPCSTR); +BOOLAPI FtpSetCurrentDirectoryW(_In_ HINTERNET, _In_ LPCWSTR); #define FtpSetCurrentDirectory WINELIB_NAME_AW(FtpSetCurrentDirectory) -BOOLAPI FtpGetCurrentDirectoryA(HINTERNET ,LPSTR ,LPDWORD); -BOOLAPI FtpGetCurrentDirectoryW(HINTERNET ,LPWSTR ,LPDWORD); -#define FtpGetCurrentDirectory WINELIB_NAME_AW(FtpGetCurrentDirectory) +BOOLAPI +FtpGetCurrentDirectoryA( + _In_ HINTERNET hConnect, + _Out_writes_(*lpdwCurrentDirectory) LPSTR lpszCurrentDirectory, + _Inout_ LPDWORD lpdwCurrentDirectory); + +BOOLAPI +FtpGetCurrentDirectoryW( + _In_ HINTERNET hConnect, + _Out_writes_(*lpdwCurrentDirectory) LPWSTR lpszCurrentDirectory, + _Inout_ LPDWORD lpdwCurrentDirectory); + +#define FtpGetCurrentDirectory WINELIB_NAME_AW(FtpGetCurrentDirectory) #define MAX_GOPHER_DISPLAY_TEXT 128 #define MAX_GOPHER_SELECTOR_TEXT 256 @@ -1093,36 +1408,113 @@ DECL_WINELIB_TYPE_AW(LPGOPHER_ATTRIBUTE_TYPE) #define GOPHER_ATTRIBUTE_ID_TREEWALK (GOPHER_ATTRIBUTE_ID_BASE + 24) #define GOPHER_ATTRIBUTE_ID_UNKNOWN (GOPHER_ATTRIBUTE_ID_BASE + 25) -BOOLAPI GopherCreateLocatorA(LPCSTR ,INTERNET_PORT ,LPCSTR , - LPCSTR ,DWORD ,LPSTR ,LPDWORD); -BOOLAPI GopherCreateLocatorW(LPCWSTR ,INTERNET_PORT ,LPCWSTR , - LPCWSTR ,DWORD ,LPWSTR ,LPDWORD); -#define GopherCreateLocator WINELIB_NAME_AW(GopherCreateLocator) +BOOLAPI +GopherCreateLocatorA( + _In_ LPCSTR lpszHost, + _In_ INTERNET_PORT nServerPort, + _In_opt_ LPCSTR lpszDisplayString, + _In_opt_ LPCSTR lpszSelectorString, + _In_ DWORD dwGopherType, + _Out_writes_opt_(*lpdwBufferLength) LPSTR lpszLocator, + _Inout_ LPDWORD lpdwBufferLength); -BOOLAPI GopherGetLocatorTypeA(LPCSTR ,LPDWORD); -BOOLAPI GopherGetLocatorTypeW(LPCWSTR ,LPDWORD); -#define GopherGetLocatorType WINELIB_NAME_AW(GopherGetLocatorType) +BOOLAPI +GopherCreateLocatorW( + _In_ LPCWSTR lpszHost, + _In_ INTERNET_PORT nServerPort, + _In_opt_ LPCWSTR lpszDisplayString, + _In_opt_ LPCWSTR lpszSelectorString, + _In_ DWORD dwGopherType, + _Out_writes_opt_(*lpdwBufferLength) LPWSTR lpszLocator, + _Inout_ LPDWORD lpdwBufferLength); -INTERNETAPI HINTERNET WINAPI GopherFindFirstFileA(HINTERNET ,LPCSTR , - LPCSTR ,LPGOPHER_FIND_DATAA ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI GopherFindFirstFileW(HINTERNET ,LPCWSTR , - LPCWSTR ,LPGOPHER_FIND_DATAW ,DWORD ,DWORD_PTR); -#define GopherFindFirstFile WINELIB_NAME_AW(GopherFindFirstFile) +#define GopherCreateLocator WINELIB_NAME_AW(GopherCreateLocator) -INTERNETAPI HINTERNET WINAPI GopherOpenFileA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI GopherOpenFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD_PTR); -#define GopherOpenFile WINELIB_NAME_AW(GopherOpenFile) +BOOLAPI GopherGetLocatorTypeA(_In_ LPCSTR, _Out_ LPDWORD); +BOOLAPI GopherGetLocatorTypeW(_In_ LPCWSTR, _Out_ LPDWORD); +#define GopherGetLocatorType WINELIB_NAME_AW(GopherGetLocatorType) -typedef BOOL (CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORA)(LPGOPHER_ATTRIBUTE_TYPEA ,DWORD); -typedef BOOL (CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORW)(LPGOPHER_ATTRIBUTE_TYPEW ,DWORD); +INTERNETAPI +HINTERNET +WINAPI +GopherFindFirstFileA( + _In_ HINTERNET hConnect, + _In_opt_ LPCSTR lpszLocator, + _In_opt_ LPCSTR lpszSearchString, + _Out_opt_ LPGOPHER_FIND_DATAA lpFindData, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +INTERNETAPI +HINTERNET +WINAPI +GopherFindFirstFileW( + _In_ HINTERNET hConnect, + _In_opt_ LPCWSTR lpszLocator, + _In_opt_ LPCWSTR lpszSearchString, + _Out_opt_ LPGOPHER_FIND_DATAW lpFindData, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +#define GopherFindFirstFile WINELIB_NAME_AW(GopherFindFirstFile) + +INTERNETAPI +HINTERNET +WINAPI +GopherOpenFileA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_opt_ LPCSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +INTERNETAPI +HINTERNET +WINAPI +GopherOpenFileW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define GopherOpenFile WINELIB_NAME_AW(GopherOpenFile) + +typedef BOOL +(CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORA)( + _In_ LPGOPHER_ATTRIBUTE_TYPEA, + _In_ DWORD); + +typedef BOOL +(CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORW)( + _In_ LPGOPHER_ATTRIBUTE_TYPEW, + _In_ DWORD); DECL_WINELIB_TYPE_AW(GOPHER_ATTRIBUTE_ENUMERATOR) -BOOLAPI GopherGetAttributeA(HINTERNET ,LPCSTR ,LPCSTR ,LPBYTE , - DWORD ,LPDWORD ,GOPHER_ATTRIBUTE_ENUMERATORA ,DWORD_PTR); -BOOLAPI GopherGetAttributeW(HINTERNET ,LPCWSTR ,LPCWSTR ,LPBYTE , - DWORD ,LPDWORD ,GOPHER_ATTRIBUTE_ENUMERATORW ,DWORD_PTR); -#define GopherGetAttribute WINELIB_NAME_AW(GopherGetAttribute) +BOOLAPI +GopherGetAttributeA( + _In_ HINTERNET hConnect, + _In_ LPCSTR lpszLocator, + _In_opt_ LPCSTR lpszAttributeName, + _At_((LPSTR) lpBuffer, _Out_writes_(dwBufferLength)) LPBYTE lpBuffer, + _In_ DWORD dwBufferLength, + _Out_ LPDWORD lpdwCharactersReturned, + _In_opt_ GOPHER_ATTRIBUTE_ENUMERATORA lpfnEnumerator, + _In_opt_ DWORD_PTR dwContext); + +BOOLAPI +GopherGetAttributeW( + _In_ HINTERNET hConnect, + _In_ LPCWSTR lpszLocator, + _In_opt_ LPCWSTR lpszAttributeName, + _At_((LPWSTR) lpBuffer, _Out_writes_(dwBufferLength)) LPBYTE lpBuffer, + _In_ DWORD dwBufferLength, + _Out_ LPDWORD lpdwCharactersReturned, + _In_opt_ GOPHER_ATTRIBUTE_ENUMERATORW lpfnEnumerator, + _In_opt_ DWORD_PTR dwContext); + +#define GopherGetAttribute WINELIB_NAME_AW(GopherGetAttribute) #define HTTP_MAJOR_VERSION 1 #define HTTP_MINOR_VERSION 0 @@ -1261,15 +1653,52 @@ BOOLAPI GopherGetAttributeW(HINTERNET ,LPCWSTR ,LPCWSTR ,LPBYTE , #define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP -INTERNETAPI HINTERNET WINAPI HttpOpenRequestA(HINTERNET ,LPCSTR ,LPCSTR ,LPCSTR , - LPCSTR ,LPCSTR * ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI HttpOpenRequestW(HINTERNET ,LPCWSTR ,LPCWSTR ,LPCWSTR , - LPCWSTR ,LPCWSTR * ,DWORD ,DWORD_PTR); -#define HttpOpenRequest WINELIB_NAME_AW(HttpOpenRequest) +INTERNETAPI +HINTERNET +WINAPI +HttpOpenRequestA( + _In_ HINTERNET hConnect, + _In_opt_ LPCSTR lpszVerb, + _In_opt_ LPCSTR lpszObjectName, + _In_opt_ LPCSTR lpszVersion, + _In_opt_ LPCSTR lpszReferrer, + _In_opt_z_ LPCSTR FAR * lplpszAcceptTypes, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); -BOOLAPI HttpAddRequestHeadersA(HINTERNET ,LPCSTR ,DWORD ,DWORD); -BOOLAPI HttpAddRequestHeadersW(HINTERNET ,LPCWSTR ,DWORD ,DWORD); -#define HttpAddRequestHeaders WINELIB_NAME_AW(HttpAddRequestHeaders) +INTERNETAPI +HINTERNET +WINAPI HttpOpenRequestW( + _In_ HINTERNET hConnect, + _In_opt_ LPCWSTR lpszVerb, + _In_opt_ LPCWSTR lpszObjectName, + _In_opt_ LPCWSTR lpszVersion, + _In_opt_ LPCWSTR lpszReferrer, + _In_opt_z_ LPCWSTR FAR * lplpszAcceptTypes, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +#define HttpOpenRequest WINELIB_NAME_AW(HttpOpenRequest) + +BOOLAPI +HttpAddRequestHeadersA( + _In_ HINTERNET hRequest, + _When_(dwHeadersLength == (DWORD) - 1, _In_z_) + _When_(dwHeadersLength != (DWORD) - 1, _In_reads_(dwHeadersLength)) + LPCSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_ DWORD dwModifiers); + +BOOLAPI +HttpAddRequestHeadersW( + _In_ HINTERNET hRequest, + _When_(dwHeadersLength == (DWORD) - 1, _In_z_) + _When_(dwHeadersLength != (DWORD) - 1, _In_reads_(dwHeadersLength)) + LPCWSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_ DWORD dwModifiers); + +#define HttpAddRequestHeaders WINELIB_NAME_AW(HttpAddRequestHeaders) #define HTTP_ADDREQ_INDEX_MASK 0x0000FFFF #define HTTP_ADDREQ_FLAGS_MASK 0xFFFF0000 @@ -1280,15 +1709,41 @@ BOOLAPI HttpAddRequestHeadersW(HINTERNET ,LPCWSTR ,DWORD ,DWORD); #define HTTP_ADDREQ_FLAG_COALESCE HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA #define HTTP_ADDREQ_FLAG_REPLACE 0x80000000 -BOOLAPI HttpSendRequestA(HINTERNET ,LPCSTR ,DWORD ,LPVOID ,DWORD); -BOOLAPI HttpSendRequestW(HINTERNET ,LPCWSTR ,DWORD ,LPVOID ,DWORD); -#define HttpSendRequest WINELIB_NAME_AW(HttpSendRequest) +BOOLAPI +HttpSendRequestA( + _In_ HINTERNET hRequest, + _In_reads_opt_(dwHeadersLength) LPCSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional, + _In_ DWORD dwOptionalLength); -INTERNETAPI BOOL WINAPI HttpSendRequestExA(HINTERNET ,LPINTERNET_BUFFERSA , - LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR); -INTERNETAPI BOOL WINAPI HttpSendRequestExW(HINTERNET ,LPINTERNET_BUFFERSW , - LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR); -#define HttpSendRequestEx WINELIB_NAME_AW(HttpSendRequestEx) +BOOLAPI +HttpSendRequestW( + _In_ HINTERNET hRequest, + _In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional, + _In_ DWORD dwOptionalLength); + +#define HttpSendRequest WINELIB_NAME_AW(HttpSendRequest) + +BOOLAPI +HttpSendRequestExA( + _In_ HINTERNET, + _In_opt_ LPINTERNET_BUFFERSA, + _Out_opt_ LPINTERNET_BUFFERSA, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +BOOLAPI +HttpSendRequestExW( + _In_ HINTERNET, + _In_opt_ LPINTERNET_BUFFERSW, + _Out_opt_ LPINTERNET_BUFFERSW, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define HttpSendRequestEx WINELIB_NAME_AW(HttpSendRequestEx) #define HSR_ASYNC WININET_API_FLAG_ASYNC #define HSR_SYNC WININET_API_FLAG_SYNC @@ -1297,18 +1752,56 @@ INTERNETAPI BOOL WINAPI HttpSendRequestExW(HINTERNET ,LPINTERNET_BUFFERSW , #define HSR_DOWNLOAD 0x00000010 #define HSR_CHUNKED 0x00000020 -INTERNETAPI BOOL WINAPI HttpEndRequestA(HINTERNET ,LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR); -INTERNETAPI BOOL WINAPI HttpEndRequestW(HINTERNET ,LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR); -#define HttpEndRequest WINELIB_NAME_AW(HttpEndRequest) +BOOLAPI +HttpEndRequestA( + _In_ HINTERNET, + _Out_opt_ LPINTERNET_BUFFERSA, + _In_ DWORD, + _In_opt_ DWORD_PTR); -BOOLAPI HttpQueryInfoA(HINTERNET ,DWORD ,LPVOID ,LPDWORD ,LPDWORD); -BOOLAPI HttpQueryInfoW(HINTERNET ,DWORD ,LPVOID ,LPDWORD ,LPDWORD); -#define HttpQueryInfo WINELIB_NAME_AW(HttpQueryInfo) +BOOLAPI +HttpEndRequestW( + _In_ HINTERNET, + _Out_opt_ LPINTERNET_BUFFERSW, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define HttpEndRequest WINELIB_NAME_AW(HttpEndRequest) + +BOOLAPI +HttpQueryInfoA( + _In_ HINTERNET hRequest, + _In_ DWORD dwInfoLevel, + _Inout_updates_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _Inout_opt_ LPDWORD lpdwIndex); + +BOOLAPI +HttpQueryInfoW( + _In_ HINTERNET hRequest, + _In_ DWORD dwInfoLevel, + _Inout_updates_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _Inout_opt_ LPDWORD lpdwIndex); + +#define HttpQueryInfo WINELIB_NAME_AW(HttpQueryInfo) BOOLAPI InternetClearAllPerSiteCookieDecisions(VOID); -BOOLAPI InternetEnumPerSiteCookieDecisionA(LPSTR,ULONG *,ULONG *,ULONG); -BOOLAPI InternetEnumPerSiteCookieDecisionW(LPWSTR,ULONG *,ULONG *,ULONG); +BOOLAPI +InternetEnumPerSiteCookieDecisionA( + _Out_writes_to_(*pcSiteNameSize, *pcSiteNameSize) LPSTR pszSiteName, + _Inout_ ULONG *pcSiteNameSize, + _Out_ ULONG *pdwDecision, + _In_ ULONG dwIndex); + +BOOLAPI +InternetEnumPerSiteCookieDecisionW( + _Out_writes_to_(*pcSiteNameSize, *pcSiteNameSize) LPWSTR pszSiteName, + _Inout_ ULONG *pcSiteNameSize, + _Out_ ULONG *pdwDecision, + _In_ ULONG dwIndex); + #define InternetEnumPerSiteCookieDecision WINELIB_NAME_AW(InternetEnumPerSiteCookieDecision) #define INTERNET_COOKIE_IS_SECURE 0x00000001 @@ -1322,33 +1815,78 @@ BOOLAPI InternetEnumPerSiteCookieDecisionW(LPWSTR,ULONG *,ULONG *,ULONG); #define INTERNET_COOKIE_IE6 0x00000400 #define INTERNET_COOKIE_IS_LEGACY 0x00000800 -BOOLAPI InternetGetCookieExA(LPCSTR,LPCSTR,LPSTR,LPDWORD,DWORD,LPVOID); -BOOLAPI InternetGetCookieExW(LPCWSTR,LPCWSTR,LPWSTR,LPDWORD,DWORD,LPVOID); +BOOLAPI +InternetGetCookieExA( + _In_ LPCSTR lpszUrl, + _In_opt_ LPCSTR lpszCookieName, + _In_reads_opt_(*lpdwSize) LPSTR lpszCookieData, + _Inout_ LPDWORD lpdwSize, + _In_ DWORD dwFlags, + _Reserved_ LPVOID lpReserved); + +BOOLAPI +InternetGetCookieExW( + _In_ LPCWSTR lpszUrl, + _In_opt_ LPCWSTR lpszCookieName, + _In_reads_opt_(*lpdwSize) LPWSTR lpszCookieData, + _Inout_ LPDWORD lpdwSize, + _In_ DWORD dwFlags, + _Reserved_ LPVOID lpReserved); + #define InternetGetCookieEx WINELIB_NAME_AW(InternetGetCookieEx) -DWORD WINAPI InternetSetCookieExA(LPCSTR,LPCSTR,LPCSTR,DWORD,DWORD_PTR); -DWORD WINAPI InternetSetCookieExW(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,DWORD_PTR); +DWORD +WINAPI +InternetSetCookieExA( + _In_ LPCSTR, + _In_opt_ LPCSTR, + _In_ LPCSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +DWORD +WINAPI +InternetSetCookieExW( + _In_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ LPCWSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + #define InternetSetCookieEx WINELIB_NAME_AW(InternetSetCookieEx) -BOOLAPI InternetGetPerSiteCookieDecisionA(LPCSTR,ULONG *); -BOOLAPI InternetGetPerSiteCookieDecisionW(LPCWSTR,ULONG *); +BOOLAPI InternetGetPerSiteCookieDecisionA(_In_ LPCSTR, _Out_ ULONG *); +BOOLAPI InternetGetPerSiteCookieDecisionW(_In_ LPCWSTR, _Out_ ULONG *); #define InternetGetPerSiteCookieDecision WINELIB_NAME_AW(InternetGetPerSiteCookieDecision) -BOOLAPI InternetSetPerSiteCookieDecisionA(LPCSTR,DWORD); -BOOLAPI InternetSetPerSiteCookieDecisionW(LPCWSTR,DWORD); +BOOLAPI InternetSetPerSiteCookieDecisionA(_In_ LPCSTR, _In_ DWORD); +BOOLAPI InternetSetPerSiteCookieDecisionW(_In_ LPCWSTR, _In_ DWORD); #define InternetSetPerSiteCookieDecision WINELIB_NAME_AW(InternetSetPerSiteCookieDecision) -BOOLAPI InternetSetCookieA(LPCSTR ,LPCSTR ,LPCSTR); -BOOLAPI InternetSetCookieW(LPCWSTR ,LPCWSTR ,LPCWSTR); +BOOLAPI InternetSetCookieA(_In_ LPCSTR, _In_opt_ LPCSTR, _In_ LPCSTR); +BOOLAPI InternetSetCookieW(_In_ LPCWSTR, _In_opt_ LPCWSTR, _In_ LPCWSTR); #define InternetSetCookie WINELIB_NAME_AW(InternetSetCookie) -BOOLAPI InternetGetCookieA(LPCSTR ,LPCSTR ,LPSTR ,LPDWORD); -BOOLAPI InternetGetCookieW(LPCWSTR ,LPCWSTR ,LPWSTR ,LPDWORD); -#define InternetGetCookie WINELIB_NAME_AW(InternetGetCookie) +BOOLAPI +InternetGetCookieA( + _In_ LPCSTR lpszUrl, + _In_opt_ LPCSTR lpszCookieName, + _Out_writes_opt_(*lpdwSize) LPSTR lpszCookieData, + _Inout_ LPDWORD lpdwSize); -INTERNETAPI DWORD WINAPI InternetAttemptConnect(DWORD); -BOOLAPI InternetCheckConnectionA(LPCSTR ,DWORD ,DWORD); -BOOLAPI InternetCheckConnectionW(LPCWSTR ,DWORD ,DWORD); +BOOLAPI +InternetGetCookieW( + _In_ LPCWSTR lpszUrl, + _In_opt_ LPCWSTR lpszCookieName, + _Out_writes_opt_(*lpdwSize) LPWSTR lpszCookieData, + _Inout_ LPDWORD lpdwSize); + +#define InternetGetCookie WINELIB_NAME_AW(InternetGetCookie) + +INTERNETAPI DWORD WINAPI InternetAttemptConnect(_In_ DWORD); + +BOOLAPI InternetCheckConnectionA(_In_ LPCSTR, _In_ DWORD, _In_ DWORD); +BOOLAPI InternetCheckConnectionW(_In_ LPCWSTR, _In_ DWORD, _In_ DWORD); #define InternetCheckConnection WINELIB_NAME_AW(InternetCheckConnection) #define FLAG_ICC_FORCE_CONNECTION 0x00000001 @@ -1372,9 +1910,34 @@ typedef struct INTERNET_AUTH_NOTIFY_DATA; -INTERNETAPI DWORD WINAPI InternetErrorDlg(HWND ,HINTERNET ,DWORD ,DWORD ,LPVOID *); -INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossingA(HWND ,LPSTR ,LPSTR ,BOOL); -INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossingW(HWND ,LPWSTR ,LPWSTR ,BOOL); +INTERNETAPI +DWORD +WINAPI +InternetErrorDlg( + _In_ HWND, + _Inout_opt_ HINTERNET, + _In_ DWORD, + _In_ DWORD, + _Inout_opt_ LPVOID *); + +INTERNETAPI +DWORD +WINAPI +InternetConfirmZoneCrossingA( + _In_ HWND, + _In_ LPSTR, + _In_ LPSTR, + _In_ BOOL); + +INTERNETAPI +DWORD +WINAPI +InternetConfirmZoneCrossingW( + _In_ HWND, + _In_ LPWSTR, + _In_ LPWSTR, + _In_ BOOL); + #define InternetConfirmZoneCrossing WINELIB_NAME_AW(InternetConfirmZoneCrossing) #define PRIVACY_TEMPLATE_NO_COOKIES 0 @@ -1391,8 +1954,24 @@ INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossingW(HWND ,LPWSTR ,LPWSTR ,BOOL #define PRIVACY_TYPE_FIRST_PARTY 0 #define PRIVACY_TYPE_THIRD_PARTY 1 -INTERNETAPI DWORD WINAPI PrivacySetZonePreferenceW(DWORD,DWORD,DWORD,LPCWSTR); -INTERNETAPI DWORD WINAPI PrivacyGetZonePreferenceW(DWORD,DWORD,LPDWORD,LPWSTR,LPDWORD); +INTERNETAPI +DWORD +WINAPI +PrivacySetZonePreferenceW( + _In_ DWORD, + _In_ DWORD, + _In_ DWORD, + _In_opt_ LPCWSTR); + +INTERNETAPI +DWORD +WINAPI +PrivacyGetZonePreferenceW( + _In_ DWORD dwZone, + _In_ DWORD dwType, + _Out_opt_ LPDWORD pdwTemplate, + _Out_writes_opt_(*pdwBufferLength) LPWSTR pszBuffer, + _Inout_opt_ LPDWORD pdwBufferLength); #define INTERNET_ERROR_BASE 12000 @@ -1564,41 +2143,139 @@ typedef struct _INTERNET_CACHE_TIMESTAMPS FILETIME ftLastModified; } INTERNET_CACHE_TIMESTAMPS, *LPINTERNET_CACHE_TIMESTAMPS; -BOOLAPI CreateUrlCacheEntryA(LPCSTR ,DWORD ,LPCSTR ,LPSTR ,DWORD); -BOOLAPI CreateUrlCacheEntryW(LPCWSTR ,DWORD ,LPCWSTR ,LPWSTR ,DWORD); -#define CreateUrlCacheEntry WINELIB_NAME_AW(CreateUrlCacheEntry) +BOOLAPI +CreateUrlCacheEntryA( + _In_ LPCSTR lpszUrlName, + _In_ DWORD dwExpectedFileSize, + _In_opt_ LPCSTR lpszFileExtension, + _Inout_updates_(MAX_PATH) LPSTR lpszFileName, + _In_ DWORD dwReserved); -BOOLAPI CommitUrlCacheEntryA(LPCSTR,LPCSTR,FILETIME,FILETIME,DWORD,LPBYTE,DWORD,LPCSTR,LPCSTR); -BOOLAPI CommitUrlCacheEntryW(LPCWSTR,LPCWSTR,FILETIME,FILETIME,DWORD,LPWSTR,DWORD,LPCWSTR,LPCWSTR); -#define CommitUrlCacheEntry WINELIB_NAME_AW(CommitUrlCacheEntry) +BOOLAPI +CreateUrlCacheEntryW( + _In_ LPCWSTR lpszUrlName, + _In_ DWORD dwExpectedFileSize, + _In_opt_ LPCWSTR lpszFileExtension, + _Inout_updates_(MAX_PATH) LPWSTR lpszFileName, + _In_ DWORD dwReserved); -BOOLAPI ResumeSuspendedDownload(HINTERNET, DWORD); +#define CreateUrlCacheEntry WINELIB_NAME_AW(CreateUrlCacheEntry) -BOOLAPI RetrieveUrlCacheEntryFileA(LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD ,DWORD); -BOOLAPI RetrieveUrlCacheEntryFileW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD ,DWORD); -#define RetrieveUrlCacheEntryFile WINELIB_NAME_AW(RetrieveUrlCacheEntryFile) +BOOLAPI +CommitUrlCacheEntryA( + _In_ LPCSTR lpszUrlName, + _In_opt_ LPCSTR lpszLocalFileName, + _In_ FILETIME ExpireTime, + _In_ FILETIME LastModifiedTime, + _In_ DWORD CacheEntryType, + _In_reads_opt_(cchHeaderInfo) LPBYTE lpHeaderInfo, + _In_ DWORD cchHeaderInfo, + _Reserved_ LPCSTR lpszFileExtension, + _In_opt_ LPCSTR lpszOriginalUrl); -BOOLAPI UnlockUrlCacheEntryFileA(LPCSTR ,DWORD); -BOOLAPI UnlockUrlCacheEntryFileW(LPCWSTR ,DWORD); +BOOLAPI +CommitUrlCacheEntryW( + _In_ LPCWSTR lpszUrlName, + _In_opt_ LPCWSTR lpszLocalFileName, + _In_ FILETIME ExpireTime, + _In_ FILETIME LastModifiedTime, + _In_ DWORD CacheEntryType, + _In_reads_opt_(cchHeaderInfo) LPWSTR lpszHeaderInfo, + _In_ DWORD cchHeaderInfo, + _Reserved_ LPCWSTR lpszFileExtension, + _In_opt_ LPCWSTR lpszOriginalUrl); + +#define CommitUrlCacheEntry WINELIB_NAME_AW(CommitUrlCacheEntry) + +BOOLAPI ResumeSuspendedDownload(_In_ HINTERNET, _In_ DWORD); + +BOOLAPI +RetrieveUrlCacheEntryFileA( + _In_ LPCSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ DWORD dwReserved); + +BOOLAPI +RetrieveUrlCacheEntryFileW( + _In_ LPCWSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ DWORD dwReserved); + +#define RetrieveUrlCacheEntryFile WINELIB_NAME_AW(RetrieveUrlCacheEntryFile) + +BOOLAPI UnlockUrlCacheEntryFileA(_In_ LPCSTR, _Reserved_ DWORD); +BOOLAPI UnlockUrlCacheEntryFileW(_In_ LPCWSTR, _Reserved_ DWORD); #define UnlockUrlCacheEntryFile WINELIB_NAME_AW(UnlockUrlCacheEntryFile) -INTERNETAPI HANDLE WINAPI RetrieveUrlCacheEntryStreamA(LPCSTR , - LPINTERNET_CACHE_ENTRY_INFOA , LPDWORD ,BOOL ,DWORD); -INTERNETAPI HANDLE WINAPI RetrieveUrlCacheEntryStreamW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW , - LPDWORD ,BOOL ,DWORD); -#define RetrieveUrlCacheEntryStream WINELIB_NAME_AW(RetrieveUrlCacheEntryStream) +INTERNETAPI +HANDLE +WINAPI +RetrieveUrlCacheEntryStreamA( + _In_ LPCSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _In_ BOOL fRandomRead, + _Reserved_ DWORD dwReserved); -BOOLAPI ReadUrlCacheEntryStream( HANDLE ,DWORD ,LPVOID ,LPDWORD ,DWORD ); -BOOLAPI UnlockUrlCacheEntryStream( HANDLE ,DWORD ); -BOOLAPI GetUrlCacheEntryInfoA(LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD); -BOOLAPI GetUrlCacheEntryInfoW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD); -#define GetUrlCacheEntryInfo WINELIB_NAME_AW(GetUrlCacheEntryInfo) +INTERNETAPI +HANDLE +WINAPI +RetrieveUrlCacheEntryStreamW( + _In_ LPCWSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _In_ BOOL fRandomRead, + _Reserved_ DWORD dwReserved); -BOOLAPI GetUrlCacheEntryInfoExA( - LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD ,LPSTR ,LPDWORD ,LPVOID ,DWORD); -BOOLAPI GetUrlCacheEntryInfoExW( - LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD ,LPWSTR ,LPDWORD ,LPVOID ,DWORD); -#define GetUrlCacheEntryInfoEx WINELIB_NAME_AW(GetUrlCacheEntryInfoEx) +#define RetrieveUrlCacheEntryStream WINELIB_NAME_AW(RetrieveUrlCacheEntryStream) + +BOOLAPI +ReadUrlCacheEntryStream( + _In_ HANDLE hUrlCacheStream, + _In_ DWORD dwLocation, + _Out_writes_bytes_(*lpdwLen) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwLen, + _Reserved_ DWORD Reserved); + +BOOLAPI UnlockUrlCacheEntryStream(_In_ HANDLE, _Reserved_ DWORD); + +BOOLAPI +GetUrlCacheEntryInfoA( + _In_ LPCSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + _Inout_opt_ LPDWORD lpcbCacheEntryInfo); + +BOOLAPI +GetUrlCacheEntryInfoW( + _In_ LPCWSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + _Inout_opt_ LPDWORD lpcbCacheEntryInfo); + +#define GetUrlCacheEntryInfo WINELIB_NAME_AW(GetUrlCacheEntryInfo) + +BOOLAPI +GetUrlCacheEntryInfoExA( + _In_ LPCSTR lpszUrl, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + _Inout_opt_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPSTR lpszRedirectUrl, + _Reserved_ LPDWORD lpcbRedirectUrl, + _Reserved_ LPVOID lpReserved, + _In_ DWORD dwFlags); + +BOOLAPI +GetUrlCacheEntryInfoExW( + _In_ LPCWSTR lpszUrl, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + _Inout_opt_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPWSTR lpszRedirectUrl, + _Reserved_ LPDWORD lpcbRedirectUrl, + _Reserved_ LPVOID lpReserved, + _In_ DWORD dwFlags); + +#define GetUrlCacheEntryInfoEx WINELIB_NAME_AW(GetUrlCacheEntryInfoEx) #define CACHE_ENTRY_ATTRIBUTE_FC 0x00000004 #define CACHE_ENTRY_HITRATE_FC 0x00000010 @@ -1610,55 +2287,185 @@ BOOLAPI GetUrlCacheEntryInfoExW( #define CACHE_ENTRY_EXEMPT_DELTA_FC 0x00000800 -BOOLAPI SetUrlCacheEntryInfoA(LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,DWORD); -BOOLAPI SetUrlCacheEntryInfoW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,DWORD); -#define SetUrlCacheEntryInfo WINELIB_NAME_AW(SetUrlCacheEntryInfo) +BOOLAPI +SetUrlCacheEntryInfoA( + _In_ LPCSTR, + _In_ LPINTERNET_CACHE_ENTRY_INFOA, + _In_ DWORD); + +BOOLAPI +SetUrlCacheEntryInfoW( + _In_ LPCWSTR, + _In_ LPINTERNET_CACHE_ENTRY_INFOW, + _In_ DWORD); + +#define SetUrlCacheEntryInfo WINELIB_NAME_AW(SetUrlCacheEntryInfo) typedef LONGLONG GROUPID; -INTERNETAPI GROUPID WINAPI CreateUrlCacheGroup(DWORD,LPVOID); -BOOLAPI DeleteUrlCacheGroup(GROUPID ,DWORD ,LPVOID); +INTERNETAPI GROUPID WINAPI CreateUrlCacheGroup(_In_ DWORD, _Reserved_ LPVOID); +BOOLAPI DeleteUrlCacheGroup(_In_ GROUPID, _In_ DWORD, _Reserved_ LPVOID); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheGroup(DWORD,DWORD,LPVOID,DWORD,GROUPID*,LPVOID); -BOOLAPI FindNextUrlCacheGroup(HANDLE,GROUPID*,LPVOID); +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheGroup( + _In_ DWORD, + _In_ DWORD, + _Reserved_ LPVOID, + _Reserved_ DWORD, + _Out_ GROUPID*, + _Reserved_ LPVOID); -BOOLAPI GetUrlCacheGroupAttributeA(GROUPID,DWORD,DWORD,LPINTERNET_CACHE_GROUP_INFOA,LPDWORD,LPVOID); -BOOLAPI GetUrlCacheGroupAttributeW(GROUPID,DWORD,DWORD,LPINTERNET_CACHE_GROUP_INFOW,LPDWORD,LPVOID); -#define GetUrlCacheGroupAttribute WINELIB_NAME_AW(GetUrlCacheGroupAttribute) +BOOLAPI FindNextUrlCacheGroup(_In_ HANDLE, _Out_ GROUPID*, _Reserved_ LPVOID); + +BOOLAPI +GetUrlCacheGroupAttributeA( + _In_ GROUPID gid, + _Reserved_ DWORD dwFlags, + _In_ DWORD dwAttributes, + _Out_writes_bytes_(*lpcbGroupInfo) LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo, + _Inout_ LPDWORD lpcbGroupInfo, + _Reserved_ LPVOID lpReserved); + +BOOLAPI +GetUrlCacheGroupAttributeW( + _In_ GROUPID gid, + _Reserved_ DWORD dwFlags, + _In_ DWORD dwAttributes, + _Out_writes_bytes_(*lpcbGroupInfo) LPINTERNET_CACHE_GROUP_INFOW lpGroupInfo, + _Inout_ LPDWORD lpcbGroupInfo, + _Reserved_ LPVOID lpReserved); + +#define GetUrlCacheGroupAttribute WINELIB_NAME_AW(GetUrlCacheGroupAttribute) #define INTERNET_CACHE_GROUP_ADD 0 #define INTERNET_CACHE_GROUP_REMOVE 1 -BOOLAPI SetUrlCacheEntryGroupA(LPCSTR,DWORD,GROUPID,LPBYTE,DWORD,LPVOID); -BOOLAPI SetUrlCacheEntryGroupW(LPCWSTR,DWORD,GROUPID,LPBYTE,DWORD,LPVOID); -#define SetUrlCacheEntryGroup WINELIB_NAME_AW(SetUrlCacheEntryGroup) +BOOLAPI +SetUrlCacheEntryGroupA( + _In_ LPCSTR, + _In_ DWORD, + _In_ GROUPID, + _Reserved_ LPBYTE, + _Reserved_ DWORD, + _Reserved_ LPVOID); -BOOLAPI SetUrlCacheGroupAttributeA(GROUPID,DWORD,DWORD,LPINTERNET_CACHE_GROUP_INFOA,LPVOID); -BOOLAPI SetUrlCacheGroupAttributeW(GROUPID,DWORD,DWORD,LPINTERNET_CACHE_GROUP_INFOW,LPVOID); -#define SetUrlCacheGroupAttribute WINELIB_NAME_AW(SetUrlCacheGroupAttribute) +BOOLAPI +SetUrlCacheEntryGroupW( + _In_ LPCWSTR, + _In_ DWORD, + _In_ GROUPID, + _Reserved_ LPBYTE, + _Reserved_ DWORD, + _Reserved_ LPVOID); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryExA( - LPCSTR ,DWORD ,DWORD ,GROUPID ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD ,LPVOID ,LPDWORD ,LPVOID ); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryExW( - LPCWSTR ,DWORD ,DWORD ,GROUPID ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD ,LPVOID ,LPDWORD ,LPVOID ); -#define FindFirstUrlCacheEntryEx WINELIB_NAME_AW(FindFirstUrlCacheEntryEx) +#define SetUrlCacheEntryGroup WINELIB_NAME_AW(SetUrlCacheEntryGroup) -BOOLAPI FindNextUrlCacheEntryExA(HANDLE ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD ,LPVOID ,LPDWORD ,LPVOID); -BOOLAPI FindNextUrlCacheEntryExW(HANDLE ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD ,LPVOID ,LPDWORD ,LPVOID); -#define FindNextUrlCacheEntryEx WINELIB_NAME_AW(FindNextUrlCacheEntryEx) +BOOLAPI +SetUrlCacheGroupAttributeA( + _In_ GROUPID, + _Reserved_ DWORD, + _In_ DWORD, + _In_ LPINTERNET_CACHE_GROUP_INFOA, + _Reserved_ LPVOID); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryA(LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD); -#define FindFirstUrlCacheEntry WINELIB_NAME_AW(FindFirstUrlCacheEntry) +BOOLAPI +SetUrlCacheGroupAttributeW( + _In_ GROUPID, + _Reserved_ DWORD, + _In_ DWORD, + _In_ LPINTERNET_CACHE_GROUP_INFOW, + _Reserved_ LPVOID); -BOOLAPI FindNextUrlCacheEntryA(HANDLE ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD); -BOOLAPI FindNextUrlCacheEntryW(HANDLE ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD); -#define FindNextUrlCacheEntry WINELIB_NAME_AW(FindNextUrlCacheEntry) +#define SetUrlCacheGroupAttribute WINELIB_NAME_AW(SetUrlCacheGroupAttribute) -BOOLAPI FindCloseUrlCache(HANDLE); +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheEntryExA( + _In_opt_ LPCSTR lpszUrlSearchPattern, + _In_ DWORD dwFlags, + _In_ DWORD dwFilter, + _In_ GROUPID GroupId, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPVOID lpGroupAttributes, + _Reserved_ LPDWORD lpcbGroupAttributes, + _Reserved_ LPVOID lpReserved); -BOOLAPI DeleteUrlCacheEntryA(LPCSTR); -BOOLAPI DeleteUrlCacheEntryW(LPCWSTR); +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheEntryExW( + _In_opt_ LPCWSTR lpszUrlSearchPattern, + _In_ DWORD dwFlags, + _In_ DWORD dwFilter, + _In_ GROUPID GroupId, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPVOID lpGroupAttributes, + _Reserved_ LPDWORD lpcbGroupAttributes, + _Reserved_ LPVOID lpReserved); + +#define FindFirstUrlCacheEntryEx WINELIB_NAME_AW(FindFirstUrlCacheEntryEx) + +BOOLAPI +FindNextUrlCacheEntryExA( + _In_ HANDLE hEnumHandle, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpNextCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPVOID lpGroupAttributes, + _Reserved_ LPDWORD lpcbGroupAttributes, + _Reserved_ LPVOID lpReserved); + +BOOLAPI +FindNextUrlCacheEntryExW( + _In_ HANDLE hEnumHandle, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpNextCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPVOID lpGroupAttributes, + _Reserved_ LPDWORD lpcbGroupAttributes, + _Reserved_ LPVOID lpReserved); + +#define FindNextUrlCacheEntryEx WINELIB_NAME_AW(FindNextUrlCacheEntryEx) + +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheEntryA( + _In_opt_ LPCSTR lpszUrlSearchPattern, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo); + +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheEntryW( + _In_opt_ LPCWSTR lpszUrlSearchPattern, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo); + +#define FindFirstUrlCacheEntry WINELIB_NAME_AW(FindFirstUrlCacheEntry) + +BOOLAPI +FindNextUrlCacheEntryA( + _In_ HANDLE hEnumHandle, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpNextCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo); + +BOOLAPI +FindNextUrlCacheEntryW( + _In_ HANDLE hEnumHandle, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpNextCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo); + +#define FindNextUrlCacheEntry WINELIB_NAME_AW(FindNextUrlCacheEntry) + +BOOLAPI FindCloseUrlCache(_In_ HANDLE); + +BOOLAPI DeleteUrlCacheEntryA(_In_ LPCSTR); +BOOLAPI DeleteUrlCacheEntryW(_In_ LPCWSTR); #define DeleteUrlCacheEntry WINELIB_NAME_AW(DeleteUrlCacheEntry) /* FCS_ flags and FreeUrlCacheSpace are no longer documented */ @@ -1670,31 +2477,50 @@ BOOLAPI FreeUrlCacheSpaceA(LPCSTR ,DWORD ,DWORD); BOOLAPI FreeUrlCacheSpaceW(LPCWSTR ,DWORD ,DWORD); #define FreeUrlCacheSpace WINELIB_NAME_AW(FreeUrlCacheSpace) +INTERNETAPI +DWORD +WINAPI +InternetDialA( + _In_ HWND, + _In_opt_ LPSTR, + _In_ DWORD, + _Out_ DWORD_PTR*, + _Reserved_ DWORD); + +INTERNETAPI +DWORD +WINAPI +InternetDialW( + _In_ HWND, + _In_opt_ LPWSTR, + _In_ DWORD, + _Out_ DWORD_PTR*, + _Reserved_ DWORD); -INTERNETAPI DWORD WINAPI InternetDialA(HWND ,LPSTR ,DWORD ,DWORD_PTR* ,DWORD); -INTERNETAPI DWORD WINAPI InternetDialW(HWND ,LPWSTR ,DWORD ,DWORD_PTR* ,DWORD); #define InternetDial WINELIB_NAME_AW(InternetDial) - #define INTERNET_DIAL_UNATTENDED 0x8000 -INTERNETAPI DWORD WINAPI InternetHangUp(DWORD_PTR ,DWORD); -BOOLAPI CreateMD5SSOHash(PWSTR,PWSTR,PWSTR,PBYTE); +INTERNETAPI DWORD WINAPI InternetHangUp(_In_ DWORD_PTR, _Reserved_ DWORD); +BOOLAPI CreateMD5SSOHash(_In_ PWSTR, _In_ PWSTR, _In_ PWSTR, _Out_ PBYTE); #define INTERENT_GOONLINE_REFRESH 0x00000001 #define INTERENT_GOONLINE_MASK 0x00000001 -INTERNETAPI BOOL WINAPI InternetGoOnlineA(LPSTR ,HWND ,DWORD); -INTERNETAPI BOOL WINAPI InternetGoOnlineW(LPWSTR ,HWND ,DWORD); + +BOOLAPI InternetGoOnlineA(_In_opt_ LPSTR, _In_ HWND, _In_ DWORD); +BOOLAPI InternetGoOnlineW(_In_opt_ LPWSTR, _In_ HWND, _In_ DWORD); #define InternetGoOnline WINELIB_NAME_AW(InternetGoOnline) -INTERNETAPI BOOL WINAPI InternetAutodial(DWORD,HWND); + +BOOLAPI InternetAutodial(_In_ DWORD, _In_opt_ HWND); #define INTERNET_AUTODIAL_FORCE_ONLINE 1 #define INTERNET_AUTODIAL_FORCE_UNATTENDED 2 #define INTERNET_AUTODIAL_FAILIFSECURITYCHECK 4 #define INTERNET_AUTODIAL_FLAGS_MASK (INTERNET_AUTODIAL_FORCE_ONLINE | INTERNET_AUTODIAL_FORCE_UNATTENDED | INTERNET_AUTODIAL_FAILIFSECURITYCHECK) -INTERNETAPI BOOL WINAPI InternetAutodialHangup(DWORD); -INTERNETAPI BOOL WINAPI InternetGetConnectedState(LPDWORD ,DWORD); + +BOOLAPI InternetAutodialHangup(_Reserved_ DWORD); +BOOLAPI InternetGetConnectedState(_Out_ LPDWORD, _Reserved_ DWORD); #define INTERNET_CONNECTION_MODEM 1 #define INTERNET_CONNECTION_LAN 2 @@ -1711,20 +2537,38 @@ typedef DWORD (CALLBACK *PFN_DIAL_HANDLER) (HWND,LPCSTR,DWORD,LPDWORD); #define INTERNET_CUSTOMDIAL_WILL_SUPPLY_STATE 2 #define INTERNET_CUSTOMDIAL_CAN_HANGUP 4 -INTERNETAPI BOOL WINAPI InternetSetDialStateA(LPCSTR ,DWORD ,DWORD); -INTERNETAPI BOOL WINAPI InternetSetDialStateW(LPCWSTR ,DWORD ,DWORD); +BOOLAPI InternetSetDialStateA(_In_opt_ LPCSTR, _In_ DWORD, _Reserved_ DWORD); +BOOLAPI InternetSetDialStateW(_In_opt_ LPCWSTR, _In_ DWORD, _Reserved_ DWORD); #define InternetSetDialState WINELIB_NAME_AW(InternetSetDialState) + #define INTERNET_DIALSTATE_DISCONNECTED 1 -BOOL WINAPI InternetGetConnectedStateExA(LPDWORD, LPSTR, DWORD, DWORD); -BOOL WINAPI InternetGetConnectedStateExW(LPDWORD, LPWSTR, DWORD, DWORD); +BOOLAPI +InternetGetConnectedStateExA( + _Out_opt_ LPDWORD lpdwFlags, + _Out_writes_opt_(cchNameLen) LPSTR lpszConnectionName, + _In_ DWORD cchNameLen, + _Reserved_ DWORD dwReserved); + +BOOLAPI +InternetGetConnectedStateExW( + _Out_opt_ LPDWORD lpdwFlags, + _Out_writes_opt_(cchNameLen) LPWSTR lpszConnectionName, + _In_ DWORD cchNameLen, + _Reserved_ DWORD dwReserved); + #define InternetGetConnectedStateEx WINELIB_NAME_AW(InternetGetConnectedStateEx) -BOOL WINAPI InternetInitializeAutoProxyDll(DWORD); -BOOL WINAPI DetectAutoProxyUrl(LPSTR, DWORD, DWORD); +BOOLAPI InternetInitializeAutoProxyDll(_In_ DWORD); + +BOOLAPI +DetectAutoProxyUrl( + _Out_writes_(cchAutoProxyUrl) PSTR pszAutoProxyUrl, + _In_ DWORD cchAutoProxyUrl, + _In_ DWORD dwDetectFlags); #ifdef __cplusplus } #endif -#endif +#endif /* _WINE_WININET_H_ */