From 6d38425b3f5e2cd5e19f751c3ccfe24fb43eb39e Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 14 Mar 2011 22:06:25 +0000 Subject: [PATCH 01/90] [NTDLL/LDR] - Rewrite TLS part of the ntdll loader. Old TLS-related messy, duplicated and hard to maintain code is gone. - Disclaimer: All new ldr-rewrite code is almost entirely based on Alex's patch made in 2006, with my improvements, bugfixes and adapting existing codepaths. - File naming convention: Files of the ldr*.c mask are considered as a new rewritten loader code. All other files in ntdll/ldr directory are old code which soon may be deprecated. svn path=/trunk/; revision=51051 --- reactos/dll/ntdll/include/ntdllp.h | 26 ++- reactos/dll/ntdll/ldr/ldrinit.c | 173 ++++++++++++++++++++ reactos/dll/ntdll/ldr/ldrutils.c | 83 ++++++++++ reactos/dll/ntdll/ldr/utils.c | 251 ++++++----------------------- reactos/dll/ntdll/ntdll.rbuild | 1 + 5 files changed, 332 insertions(+), 202 deletions(-) create mode 100644 reactos/dll/ntdll/ldr/ldrutils.c diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index b413f3840bb..41e996c17b1 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -8,6 +8,28 @@ /* INCLUDES ******************************************************************/ +extern BOOLEAN ShowSnaps; + +typedef struct _LDRP_TLS_DATA +{ + LIST_ENTRY TlsLinks; + IMAGE_TLS_DIRECTORY TlsDirectory; +} LDRP_TLS_DATA, *PLDRP_TLS_DATA; + +typedef BOOL +(NTAPI *PDLLMAIN_FUNC)(HANDLE hInst, + ULONG ul_reason_for_call, + LPVOID lpReserved); + + +/* ldrinit.c */ +NTSTATUS NTAPI LdrpInitializeTls(VOID); +NTSTATUS NTAPI LdrpAllocateTls(VOID); +VOID NTAPI LdrpFreeTls(VOID); +VOID NTAPI LdrpTlsCallback(PVOID BaseAddress, ULONG Reason); +BOOLEAN NTAPI LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint, PVOID BaseAddress, ULONG Reason, PVOID Context); + + /* FIXME: Cleanup this mess */ typedef NTSTATUS (NTAPI *PEPFUNC)(PPEB); NTSTATUS LdrMapSections(HANDLE ProcessHandle, @@ -23,10 +45,6 @@ PEPFUNC LdrPEStartup (PVOID ImageBase, HANDLE SectionHandle, PLDR_DATA_TABLE_ENTRY* Module, PWSTR FullDosName); -typedef BOOL -(NTAPI *PDLLMAIN_FUNC)(HANDLE hInst, - ULONG ul_reason_for_call, - LPVOID lpReserved); extern HANDLE WindowsApiPort; diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index 77baa0a5ed8..9d4e378d22a 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -20,6 +20,16 @@ HKEY Wow64ExecOptionsKey; UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"); UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); +//RTL_BITMAP TlsBitMap; +//RTL_BITMAP TlsExpansionBitMap; +//RTL_BITMAP FlsBitMap; +BOOLEAN LdrpImageHasTls; +LIST_ENTRY LdrpTlsList; +ULONG LdrpNumberOfTlsEntries; +ULONG LdrpNumberOfProcessors; + +BOOLEAN ShowSnaps; + /* FUNCTIONS *****************************************************************/ /* @@ -317,4 +327,167 @@ LdrQueryImageFileExecutionOptions(IN PUNICODE_STRING SubKey, FALSE); } +NTSTATUS +NTAPI +LdrpInitializeTls(VOID) +{ + PLIST_ENTRY NextEntry, ListHead; + PLDR_DATA_TABLE_ENTRY LdrEntry; + PIMAGE_TLS_DIRECTORY TlsDirectory; + PLDRP_TLS_DATA TlsData; + ULONG Size; + + /* Initialize the TLS List */ + InitializeListHead(&LdrpTlsList); + + /* Loop all the modules */ + ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) + { + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + NextEntry = NextEntry->Flink; + + /* Get the TLS directory */ + TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_TLS, + &Size); + + /* Check if we have a directory */ + if (!TlsDirectory) continue; + + /* Check if the image has TLS */ + if (!LdrpImageHasTls) LdrpImageHasTls = TRUE; + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: Tls Found in %wZ at %p\n", + &LdrEntry->BaseDllName, + TlsDirectory); + } + + /* Allocate an entry */ + TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA)); + if (!TlsData) return STATUS_NO_MEMORY; + + /* Lock the DLL and mark it for TLS Usage */ + LdrEntry->LoadCount = -1; + LdrEntry->TlsIndex = -1; + + /* Save the cached TLS data */ + TlsData->TlsDirectory = *TlsDirectory; + InsertTailList(&LdrpTlsList, &TlsData->TlsLinks); + + /* Update the index */ + *(PLONG)TlsData->TlsDirectory.AddressOfIndex = LdrpNumberOfTlsEntries; + TlsData->TlsDirectory.Characteristics = LdrpNumberOfTlsEntries++; + } + + /* Done setting up TLS, allocate entries */ + return LdrpAllocateTls(); +} + +NTSTATUS +NTAPI +LdrpAllocateTls(VOID) +{ + PTEB Teb = NtCurrentTeb(); + PLIST_ENTRY NextEntry, ListHead; + PLDRP_TLS_DATA TlsData; + ULONG TlsDataSize; + PVOID *TlsVector; + + /* Check if we have any entries */ + if (LdrpNumberOfTlsEntries) + return 0; + + /* Allocate the vector array */ + TlsVector = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + LdrpNumberOfTlsEntries * sizeof(PVOID)); + if (!TlsVector) return STATUS_NO_MEMORY; + Teb->ThreadLocalStoragePointer = TlsVector; + + /* Loop the TLS Array */ + ListHead = &LdrpTlsList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the entry */ + TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks); + NextEntry = NextEntry->Flink; + + /* Allocate this vector */ + TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData - + TlsData->TlsDirectory.StartAddressOfRawData; + TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + TlsDataSize); + if (!TlsVector[TlsData->TlsDirectory.Characteristics]) + { + /* Out of memory */ + return STATUS_NO_MEMORY; + } + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: TlsVector %x Index %d = %x copied from %x to %x\n", + TlsVector, + TlsData->TlsDirectory.Characteristics, + &TlsVector[TlsData->TlsDirectory.Characteristics], + TlsData->TlsDirectory.StartAddressOfRawData, + TlsVector[TlsData->TlsDirectory.Characteristics]); + } + + /* Copy the data */ + RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics], + (PVOID)TlsData->TlsDirectory.StartAddressOfRawData, + TlsDataSize); + } + + /* Done */ + return STATUS_SUCCESS; +} + +VOID +NTAPI +LdrpFreeTls(VOID) +{ + PLIST_ENTRY ListHead, NextEntry; + PLDRP_TLS_DATA TlsData; + PVOID *TlsVector; + PTEB Teb = NtCurrentTeb(); + + /* Get a pointer to the vector array */ + TlsVector = Teb->ThreadLocalStoragePointer; + if (!TlsVector) return; + + /* Loop through it */ + ListHead = &LdrpTlsList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks); + NextEntry = NextEntry->Flink; + + /* Free each entry */ + if (TlsVector[TlsData->TlsDirectory.Characteristics]) + { + RtlFreeHeap(RtlGetProcessHeap(), + 0, + TlsVector[TlsData->TlsDirectory.Characteristics]); + } + } + + /* Free the array itself */ + RtlFreeHeap(RtlGetProcessHeap(), + 0, + TlsVector); +} + + /* EOF */ diff --git a/reactos/dll/ntdll/ldr/ldrutils.c b/reactos/dll/ntdll/ldr/ldrutils.c new file mode 100644 index 00000000000..29534cdd992 --- /dev/null +++ b/reactos/dll/ntdll/ldr/ldrutils.c @@ -0,0 +1,83 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS NT User-Mode Library + * FILE: dll/ntdll/ldr/ldrutils.c + * PURPOSE: Internal Loader Utility Functions + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint, + PVOID BaseAddress, + ULONG Reason, + PVOID Context) +{ + /* Call the entry */ + return EntryPoint(BaseAddress, Reason, Context); +} + +VOID +NTAPI +LdrpTlsCallback(PVOID BaseAddress, ULONG Reason) +{ + PIMAGE_TLS_DIRECTORY TlsDirectory; + PIMAGE_TLS_CALLBACK *Array, Callback; + ULONG Size; + + /* Get the TLS Directory */ + TlsDirectory = RtlImageDirectoryEntryToData(BaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_TLS, + &Size); + + /* Protect against invalid pointers */ + _SEH2_TRY + { + /* Make sure it's valid and we have an array */ + if (TlsDirectory && (Array = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks)) + { + /* Display debug */ + if (ShowSnaps) + { + DPRINT1("LDR: Tls Callbacks Found. Imagebase %p Tls %p CallBacks %p\n", + BaseAddress, TlsDirectory, Array); + } + + /* Loop the array */ + while (*Array) + { + /* Get the TLS Entrypoint */ + Callback = *Array++; + + /* Display debug */ + if (ShowSnaps) + { + DPRINT1("LDR: Calling Tls Callback Imagebase %p Function %p\n", + BaseAddress, Callback); + } + + /* Call it */ + LdrpCallDllEntry((PDLLMAIN_FUNC)Callback, BaseAddress, Reason, NULL); + } + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Do nothing */ + } + _SEH2_END; +} + +/* EOF */ diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index e7213b3df07..41c2802cafb 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -31,19 +31,7 @@ #define TRACE_LDR(...) if (RtlGetNtGlobalFlags() & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(__VA_ARGS__); } #endif -typedef struct _TLS_DATA -{ - PVOID StartAddressOfRawData; - DWORD TlsDataSize; - DWORD TlsZeroSize; - PIMAGE_TLS_CALLBACK *TlsAddressOfCallBacks; - PLDR_DATA_TABLE_ENTRY Module; -} TLS_DATA, *PTLS_DATA; - static BOOLEAN LdrpDllShutdownInProgress = FALSE; -static PTLS_DATA LdrpTlsArray = NULL; -static ULONG LdrpTlsCount = 0; -static ULONG LdrpTlsSize = 0; static HANDLE LdrpKnownDllsDirHandle = NULL; static UNICODE_STRING LdrpKnownDllPath = {0, 0, NULL}; static PLDR_DATA_TABLE_ENTRY LdrpLastModule = NULL; @@ -118,51 +106,6 @@ static __inline LONG LdrpIncrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEA return LoadCount; } -static __inline VOID LdrpAcquireTlsSlot(PLDR_DATA_TABLE_ENTRY Module, ULONG Size, BOOLEAN Locked) -{ - if (!Locked) - { - RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); - } - Module->TlsIndex = (SHORT)LdrpTlsCount; - LdrpTlsCount++; - LdrpTlsSize += Size; - if (!Locked) - { - RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); - } -} - -static __inline VOID LdrpTlsCallback(PLDR_DATA_TABLE_ENTRY Module, ULONG dwReason) -{ - PIMAGE_TLS_CALLBACK *TlsCallback; - if (Module->TlsIndex != 0xFFFF && Module->LoadCount == LDRP_PROCESS_CREATION_TIME) - { - TlsCallback = LdrpTlsArray[Module->TlsIndex].TlsAddressOfCallBacks; - if (TlsCallback) - { - while (*TlsCallback) - { - TRACE_LDR("%wZ - Calling tls callback at %x\n", - &Module->BaseDllName, *TlsCallback); - (*TlsCallback)(Module->DllBase, dwReason, NULL); - TlsCallback++; - } - } - } -} - -static BOOLEAN LdrpCallDllEntry(PLDR_DATA_TABLE_ENTRY Module, DWORD dwReason, PVOID lpReserved) -{ - if (!(Module->Flags & LDRP_IMAGE_DLL) || - Module->EntryPoint == 0) - { - return TRUE; - } - LdrpTlsCallback(Module, dwReason); - return ((PDLLMAIN_FUNC)Module->EntryPoint)(Module->DllBase, dwReason, lpReserved); -} - static PWSTR LdrpQueryAppPaths(IN PCWSTR ImageName) { @@ -269,127 +212,6 @@ LdrpQueryAppPaths(IN PCWSTR ImageName) return Path; } -static NTSTATUS -LdrpInitializeTlsForThread(VOID) -{ - PVOID* TlsPointers; - PTLS_DATA TlsInfo; - PVOID TlsData; - ULONG i; - PTEB Teb = NtCurrentTeb(); - - DPRINT("LdrpInitializeTlsForThread() called for %wZ\n", &ExeModule->BaseDllName); - - Teb->StaticUnicodeString.Length = 0; - Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer); - Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer; - - if (LdrpTlsCount > 0) - { - TlsPointers = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - LdrpTlsCount * sizeof(PVOID) + LdrpTlsSize); - if (TlsPointers == NULL) - { - DPRINT1("failed to allocate thread tls data\n"); - return STATUS_NO_MEMORY; - } - - TlsData = (PVOID)((ULONG_PTR)TlsPointers + LdrpTlsCount * sizeof(PVOID)); - Teb->ThreadLocalStoragePointer = TlsPointers; - - TlsInfo = LdrpTlsArray; - for (i = 0; i < LdrpTlsCount; i++, TlsInfo++) - { - TRACE_LDR("Initialize tls data for %wZ\n", &TlsInfo->Module->BaseDllName); - TlsPointers[i] = TlsData; - if (TlsInfo->TlsDataSize) - { - memcpy(TlsData, TlsInfo->StartAddressOfRawData, TlsInfo->TlsDataSize); - TlsData = (PVOID)((ULONG_PTR)TlsData + TlsInfo->TlsDataSize); - } - if (TlsInfo->TlsZeroSize) - { - memset(TlsData, 0, TlsInfo->TlsZeroSize); - TlsData = (PVOID)((ULONG_PTR)TlsData + TlsInfo->TlsZeroSize); - } - } - } - - DPRINT("LdrpInitializeTlsForThread() done\n"); - return STATUS_SUCCESS; -} - -static NTSTATUS -LdrpInitializeTlsForProccess(VOID) -{ - PLIST_ENTRY ModuleListHead; - PLIST_ENTRY Entry; - PLDR_DATA_TABLE_ENTRY Module; - PIMAGE_TLS_DIRECTORY TlsDirectory; - PTLS_DATA TlsData; - ULONG Size; - - DPRINT("LdrpInitializeTlsForProccess() called for %wZ\n", &ExeModule->BaseDllName); - - if (LdrpTlsCount > 0) - { - LdrpTlsArray = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - LdrpTlsCount * sizeof(TLS_DATA)); - if (LdrpTlsArray == NULL) - { - DPRINT1("Failed to allocate global tls data\n"); - return STATUS_NO_MEMORY; - } - - ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; - Entry = ModuleListHead->Flink; - while (Entry != ModuleListHead) - { - Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - if (Module->LoadCount == LDRP_PROCESS_CREATION_TIME && - Module->TlsIndex != 0xFFFF) - { - TlsDirectory = (PIMAGE_TLS_DIRECTORY) - RtlImageDirectoryEntryToData(Module->DllBase, - TRUE, - IMAGE_DIRECTORY_ENTRY_TLS, - &Size); - ASSERT(Module->TlsIndex < LdrpTlsCount); - TlsData = &LdrpTlsArray[Module->TlsIndex]; - TlsData->StartAddressOfRawData = (PVOID)TlsDirectory->StartAddressOfRawData; - TlsData->TlsDataSize = TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData; - TlsData->TlsZeroSize = TlsDirectory->SizeOfZeroFill; - if (TlsDirectory->AddressOfCallBacks) - TlsData->TlsAddressOfCallBacks = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks; - else - TlsData->TlsAddressOfCallBacks = NULL; - TlsData->Module = Module; -#if 0 - DbgPrint("TLS directory for %wZ\n", &Module->BaseDllName); - DbgPrint("StartAddressOfRawData: %x\n", TlsDirectory->StartAddressOfRawData); - DbgPrint("EndAddressOfRawData: %x\n", TlsDirectory->EndAddressOfRawData); - DbgPrint("SizeOfRawData: %d\n", TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData); - DbgPrint("AddressOfIndex: %x\n", TlsDirectory->AddressOfIndex); - DbgPrint("AddressOfCallBacks: %x\n", TlsDirectory->AddressOfCallBacks); - DbgPrint("SizeOfZeroFill: %d\n", TlsDirectory->SizeOfZeroFill); - DbgPrint("Characteristics: %x\n", TlsDirectory->Characteristics); -#endif - /* - * FIXME: - * Is this region allways writable ? - */ - *(PULONG)TlsDirectory->AddressOfIndex = Module->TlsIndex; - } - Entry = Entry->Flink; - } - } - - DPRINT("LdrpInitializeTlsForProccess() done\n"); - return STATUS_SUCCESS; -} - VOID LdrpInitLoader(VOID) { @@ -2093,11 +1915,6 @@ Success: } } - if (TlsDirectory && TlsSize > 0) - { - LdrpAcquireTlsSlot(Module, TlsSize, FALSE); - } - if (Module->EntryPointActivationContext) RtlDeactivateActivationContext( 0, cookie ); return STATUS_SUCCESS; @@ -2216,14 +2033,14 @@ PEPFUNC LdrPEStartup (PVOID ImageBase, } DPRINT("Fixup done\n"); RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); - Status = LdrpInitializeTlsForProccess(); + Status = LdrpInitializeTls(); if (NT_SUCCESS(Status)) { Status = LdrpAttachProcess(); } if (NT_SUCCESS(Status)) { - LdrpTlsCallback(*Module, DLL_PROCESS_ATTACH); + LdrpTlsCallback((*Module)->DllBase, DLL_PROCESS_ATTACH); } @@ -2768,9 +2585,21 @@ LdrpDetachProcess(BOOLEAN UnloadAll) { TRACE_LDR("Unload %wZ - Calling entry point at %x\n", &Module->BaseDllName, Module->EntryPoint); - LdrpCallDllEntry(Module, - DLL_PROCESS_DETACH, - (PVOID)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0)); + + /* Check if it has TLS */ + if (Module->TlsIndex) + { + /* Call TLS */ + LdrpTlsCallback(Module->DllBase, DLL_PROCESS_ATTACH); + } + + if ((Module->Flags & LDRP_IMAGE_DLL) && Module->EntryPoint) + { + LdrpCallDllEntry(Module->EntryPoint, + Module->DllBase, + DLL_PROCESS_DETACH, + (PVOID)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0)); + } } else { @@ -2855,7 +2684,19 @@ LdrpAttachProcess(VOID) Module->Flags |= LDRP_LOAD_IN_PROGRESS; TRACE_LDR("%wZ loaded - Calling init routine at %x for process attaching\n", &Module->BaseDllName, Module->EntryPoint); - Result = LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0)); + + /* Check if it has TLS */ + if (Module->TlsIndex && FALSE/*Context*/) + { + /* Call TLS */ + LdrpTlsCallback(Module->DllBase, DLL_PROCESS_ATTACH); + } + + if ((Module->Flags & LDRP_IMAGE_DLL) && Module->EntryPoint) + Result = LdrpCallDllEntry(Module->EntryPoint, Module->DllBase, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0)); + else + Result = TRUE; + if (!Result) { Status = STATUS_DLL_INIT_FAILED; @@ -2915,7 +2756,7 @@ LdrpAttachThread (VOID) RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); - Status = LdrpInitializeTlsForThread(); + Status = LdrpAllocateTls(); if (NT_SUCCESS(Status)) { @@ -2931,14 +2772,23 @@ LdrpAttachThread (VOID) { TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n", &Module->BaseDllName, Module->EntryPoint); - LdrpCallDllEntry(Module, DLL_THREAD_ATTACH, NULL); + + /* Check if it has TLS */ + if (Module->TlsIndex) + { + /* Call TLS */ + LdrpTlsCallback(Module->DllBase, DLL_THREAD_ATTACH); + } + + if ((Module->Flags & LDRP_IMAGE_DLL) && Module->EntryPoint) + LdrpCallDllEntry(Module->EntryPoint, Module->DllBase, DLL_THREAD_ATTACH, NULL); } Entry = Entry->Flink; } Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink; Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - LdrpTlsCallback(Module, DLL_THREAD_ATTACH); + LdrpTlsCallback(Module->DllBase, DLL_THREAD_ATTACH); } RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); @@ -2976,18 +2826,23 @@ LdrShutdownThread (VOID) { TRACE_LDR("%wZ - Calling entry point at %x for thread detaching\n", &Module->BaseDllName, Module->EntryPoint); - LdrpCallDllEntry(Module, DLL_THREAD_DETACH, NULL); + /* Check if it has TLS */ + if (Module->TlsIndex) + { + /* Call TLS */ + LdrpTlsCallback(Module->DllBase, DLL_THREAD_DETACH); + } + + if ((Module->Flags & LDRP_IMAGE_DLL) && Module->EntryPoint) + LdrpCallDllEntry(Module->EntryPoint, Module->DllBase, DLL_THREAD_DETACH, NULL); } Entry = Entry->Blink; } + /* Free TLS */ + LdrpFreeTls(); RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); - if (LdrpTlsArray) - { - RtlFreeHeap (RtlGetProcessHeap(), 0, NtCurrentTeb()->ThreadLocalStoragePointer); - } - DPRINT("LdrShutdownThread() done\n"); return STATUS_SUCCESS; diff --git a/reactos/dll/ntdll/ntdll.rbuild b/reactos/dll/ntdll/ntdll.rbuild index 30a97ef00cc..0a319e5603e 100644 --- a/reactos/dll/ntdll/ntdll.rbuild +++ b/reactos/dll/ntdll/ntdll.rbuild @@ -48,6 +48,7 @@ ldrinit.c + ldrutils.c startup.c utils.c actctx.c From f565766808b6dad7a5d8e90c0db9aa0676c69e97 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Mon, 14 Mar 2011 22:25:50 +0000 Subject: [PATCH 02/90] [HAL\x86] Define a flag when building HAL with ACPI support svn path=/trunk/; revision=51052 --- reactos/hal/halx86/hal_generic_acpi.rbuild | 1 + reactos/hal/halx86/halacpi.rbuild | 1 + 2 files changed, 2 insertions(+) diff --git a/reactos/hal/halx86/hal_generic_acpi.rbuild b/reactos/hal/halx86/hal_generic_acpi.rbuild index 97501cb1823..babc0e8dfd1 100644 --- a/reactos/hal/halx86/hal_generic_acpi.rbuild +++ b/reactos/hal/halx86/hal_generic_acpi.rbuild @@ -6,6 +6,7 @@ include + halacpi.c diff --git a/reactos/hal/halx86/halacpi.rbuild b/reactos/hal/halx86/halacpi.rbuild index d380cf6889e..2037d9f759d 100644 --- a/reactos/hal/halx86/halacpi.rbuild +++ b/reactos/hal/halx86/halacpi.rbuild @@ -8,6 +8,7 @@ include + hal_generic hal_generic_acpi hal_generic_up From 92d94fdb7c33351462b7e2240bcbbf20ffa1480b Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Tue, 15 Mar 2011 15:37:09 +0000 Subject: [PATCH 03/90] [SHELL32] Fix missing "Open" menu entry on right click for All Users desktop shortcuts. Patch by Thomas Faber See issue #5998 for more details. svn path=/trunk/; revision=51053 --- reactos/dll/win32/shell32/clipboard.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/reactos/dll/win32/shell32/clipboard.c b/reactos/dll/win32/shell32/clipboard.c index 1bdae631878..0c989c6ddd5 100644 --- a/reactos/dll/win32/shell32/clipboard.c +++ b/reactos/dll/win32/shell32/clipboard.c @@ -47,26 +47,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { UINT i; - int rootlen = 0,size = 0; - WCHAR wszRootPath[MAX_PATH]; + int size = 0; WCHAR wszFileName[MAX_PATH]; HGLOBAL hGlobal; DROPFILES *pDropFiles; int offset; + LPITEMIDLIST *pidls; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); + pidls = HeapAlloc(GetProcessHeap(), 0, cidl * sizeof *pidls); + if (!pidls) return NULL; + /* get the size needed */ size = sizeof(DROPFILES); - SHGetPathFromIDListW(pidlRoot, wszRootPath); - PathAddBackslashW(wszRootPath); - rootlen = wcslen(wszRootPath); - for (i=0; ipFiles = offset * sizeof(WCHAR); pDropFiles->fWide = TRUE; - wcscpy(wszFileName, wszRootPath); - for (i=0; i Date: Tue, 15 Mar 2011 18:41:17 +0000 Subject: [PATCH 04/90] [DRIVERS] - Change () to (VOID) in function declarators. Part 5/XX. svn path=/trunk/; revision=51054 --- reactos/drivers/base/kddll/kddll.h | 2 +- reactos/drivers/filesystems/ext2/inc/protos.h | 2 +- reactos/drivers/filesystems/fastfat_new/fastfat.h | 2 +- reactos/drivers/network/lan/include/lan.h | 4 ++-- reactos/drivers/network/ndis/include/miniport.h | 2 +- reactos/drivers/network/tcpip/include/icmp.h | 4 ++-- reactos/drivers/network/tcpip/include/interface.h | 2 +- reactos/drivers/network/tcpip/include/lan.h | 4 ++-- reactos/drivers/network/tcpip/include/lock.h | 2 +- reactos/drivers/storage/classpnp/debug.h | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/reactos/drivers/base/kddll/kddll.h b/reactos/drivers/base/kddll/kddll.h index b6119e39dcc..50964141b8f 100644 --- a/reactos/drivers/base/kddll/kddll.h +++ b/reactos/drivers/base/kddll/kddll.h @@ -70,7 +70,7 @@ KdpReceiveByte(OUT PBYTE OutByte); KDP_STATUS NTAPI -KdpPollBreakIn(); +KdpPollBreakIn(VOID); #if 0 diff --git a/reactos/drivers/filesystems/ext2/inc/protos.h b/reactos/drivers/filesystems/ext2/inc/protos.h index 20143c3c5bd..864dfc2b820 100644 --- a/reactos/drivers/filesystems/ext2/inc/protos.h +++ b/reactos/drivers/filesystems/ext2/inc/protos.h @@ -256,7 +256,7 @@ extern LONGLONG NTAPI Ext2Align64( LONGLONG NumberToBeAligned, LONGLONG Alignment); -extern ULONG NTAPI Ext2GetCurrentTime(); +extern ULONG NTAPI Ext2GetCurrentTime(VOID); /************************************************************************* * Prototypes for the file cleanup.c diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.h b/reactos/drivers/filesystems/fastfat_new/fastfat.h index fbbf272c413..f00bca4a832 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.h +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.h @@ -368,7 +368,7 @@ FatRemoveNames(IN PFAT_IRP_CONTEXT IrpContext, IN PFCB Fcb); PCCB NTAPI -FatCreateCcb(); +FatCreateCcb(VOID); VOID NTAPI FatDeleteCcb(IN PFAT_IRP_CONTEXT IrpContext, diff --git a/reactos/drivers/network/lan/include/lan.h b/reactos/drivers/network/lan/include/lan.h index fb7e1e0a4e3..1e4be2f22e8 100644 --- a/reactos/drivers/network/lan/include/lan.h +++ b/reactos/drivers/network/lan/include/lan.h @@ -156,8 +156,8 @@ NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, VOID FreeNdisPacketX( PNDIS_PACKET Packet, PCHAR File, UINT Line ); -NDIS_STATUS InitNdisPools(); -VOID CloseNdisPools(); +NDIS_STATUS InitNdisPools(VOID); +VOID CloseNdisPools(VOID); PLAN_ADAPTER FindAdapterByIndex( PLAN_DEVICE_EXT DeviceExt, UINT Index ); diff --git a/reactos/drivers/network/ndis/include/miniport.h b/reactos/drivers/network/ndis/include/miniport.h index ad4de2a81e3..a5b8c8f206d 100644 --- a/reactos/drivers/network/ndis/include/miniport.h +++ b/reactos/drivers/network/ndis/include/miniport.h @@ -169,7 +169,7 @@ NdisFindDevice( PUINT SlotNumber); VOID -NdisStartDevices(); +NdisStartDevices(VOID); VOID NTAPI diff --git a/reactos/drivers/network/tcpip/include/icmp.h b/reactos/drivers/network/tcpip/include/icmp.h index aaaefa24b5f..e0902e02737 100644 --- a/reactos/drivers/network/tcpip/include/icmp.h +++ b/reactos/drivers/network/tcpip/include/icmp.h @@ -55,9 +55,9 @@ NTSTATUS ICMPSendDatagram( ULONG DataSize, PULONG DataUsed ); -NTSTATUS ICMPStartup(); +NTSTATUS ICMPStartup(VOID); -NTSTATUS ICMPShutdown(); +NTSTATUS ICMPShutdown(VOID); VOID ICMPReceive( PIP_INTERFACE Interface, diff --git a/reactos/drivers/network/tcpip/include/interface.h b/reactos/drivers/network/tcpip/include/interface.h index c79bcabce3f..72a69410669 100644 --- a/reactos/drivers/network/tcpip/include/interface.h +++ b/reactos/drivers/network/tcpip/include/interface.h @@ -7,7 +7,7 @@ NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface, ULONG Type, PULONG Address ); -UINT CountInterfaces(); +UINT CountInterfaces(VOID); UINT CountInterfaceAddresses( PIP_INTERFACE Interface ); NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed ); NTSTATUS GetInterfaceName( PIP_INTERFACE Interface, PCHAR NameBuffer, diff --git a/reactos/drivers/network/tcpip/include/lan.h b/reactos/drivers/network/tcpip/include/lan.h index 226d354e421..2792c25c6da 100644 --- a/reactos/drivers/network/tcpip/include/lan.h +++ b/reactos/drivers/network/tcpip/include/lan.h @@ -94,8 +94,8 @@ NTSTATUS LANRegisterProtocol( VOID NTAPI LANUnregisterProtocol(VOID); -VOID LANStartup(); -VOID LANShutdown(); +VOID LANStartup(VOID); +VOID LANShutdown(VOID); NTSTATUS TcpipLanGetDwordOid( PIP_INTERFACE Interface, NDIS_OID Oid, PULONG Result ); diff --git a/reactos/drivers/network/tcpip/include/lock.h b/reactos/drivers/network/tcpip/include/lock.h index cac01ebeb6e..be231520778 100644 --- a/reactos/drivers/network/tcpip/include/lock.h +++ b/reactos/drivers/network/tcpip/include/lock.h @@ -1,6 +1,6 @@ #pragma once -extern KIRQL TcpipGetCurrentIrql(); +extern KIRQL TcpipGetCurrentIrql(VOID); extern VOID TcpipInitializeSpinLock( PKSPIN_LOCK SpinLock ); extern VOID TcpipAcquireSpinLock( PKSPIN_LOCK SpinLock, PKIRQL Irql ); extern VOID TcpipReleaseSpinLock( PKSPIN_LOCK SpinLock, KIRQL Irql ); diff --git a/reactos/drivers/storage/classpnp/debug.h b/reactos/drivers/storage/classpnp/debug.h index 2fa64c41fe1..1bcbf6b7eeb 100644 --- a/reactos/drivers/storage/classpnp/debug.h +++ b/reactos/drivers/storage/classpnp/debug.h @@ -113,7 +113,7 @@ VOID ClassDebugPrint(CLASS_DEBUG_LEVEL DebugPrintLevel, PCCHAR DebugMessage, ... #define DBGCHECKRETURNEDPKT(_pkt) DbgCheckReturnedPkt(_pkt) #define DBGGETSRBSTATUSSTR(_pSrb) DbgGetSrbStatusStr(_pSrb) - VOID ClasspInitializeDebugGlobals(); + VOID ClasspInitializeDebugGlobals(VOID); char *DbgGetIoctlStr(ULONG ioctl); char *DbgGetScsiOpStr(PSCSI_REQUEST_BLOCK Srb); char *DbgGetSenseCodeStr(PSCSI_REQUEST_BLOCK Srb); From 62fce851b170e18f9c83802b2871a2fe04567463 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 15 Mar 2011 18:50:31 +0000 Subject: [PATCH 05/90] [SETUP] - Mario Kacmar: Added 'VBR only' as possible option to the reactos.exe - it is necessary to add it to other languages (I would not mess up codepages). See issue #5734 for more details. svn path=/trunk/; revision=51055 --- reactos/base/setup/reactos/lang/cs-CZ.rc | 5 ++- reactos/base/setup/reactos/lang/de-DE.rc | 5 ++- reactos/base/setup/reactos/lang/en-US.rc | 5 ++- reactos/base/setup/reactos/lang/fr-FR.rc | 5 ++- reactos/base/setup/reactos/lang/sk-SK.rc | 7 +-- reactos/base/setup/reactos/resource.h | 55 ++++++++++++------------ 6 files changed, 44 insertions(+), 38 deletions(-) diff --git a/reactos/base/setup/reactos/lang/cs-CZ.rc b/reactos/base/setup/reactos/lang/cs-CZ.rc index 2ee2f142c9a..505042b65f9 100644 --- a/reactos/base/setup/reactos/lang/cs-CZ.rc +++ b/reactos/base/setup/reactos/lang/cs-CZ.rc @@ -91,8 +91,9 @@ BEGIN CONTROL "Boot loader installation", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41 - CONTROL "Install boot loader on the hard disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 - CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11 + CONTROL "Install boot loader on the hard disk (MBR and VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 + CONTROL "Install boot loader on the hard disk (VBR only)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11 + CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11 PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE PUSHBUTTON "&Cancel", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE END diff --git a/reactos/base/setup/reactos/lang/de-DE.rc b/reactos/base/setup/reactos/lang/de-DE.rc index 4c44f64b83c..1c8a1f4fb0e 100644 --- a/reactos/base/setup/reactos/lang/de-DE.rc +++ b/reactos/base/setup/reactos/lang/de-DE.rc @@ -91,8 +91,9 @@ BEGIN CONTROL "Bootloader-Installation", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41 - CONTROL "Installiere Bootloader auf Festplatte (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 - CONTROL "Keine Bootloader-Installation", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11 + CONTROL "Installiere Bootloader auf Festplatte (MBR und VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 + CONTROL "Installiere Bootloader auf Festplatte (VBR nur)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11 + CONTROL "Keine Bootloader-Installation", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11 PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE PUSHBUTTON "&Abbrechen", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE END diff --git a/reactos/base/setup/reactos/lang/en-US.rc b/reactos/base/setup/reactos/lang/en-US.rc index b548ba979fc..e0f4eccf865 100644 --- a/reactos/base/setup/reactos/lang/en-US.rc +++ b/reactos/base/setup/reactos/lang/en-US.rc @@ -91,8 +91,9 @@ BEGIN CONTROL "Boot loader installation", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41 - CONTROL "Install boot loader on the hard disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 - CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11 + CONTROL "Install boot loader on the hard disk (MBR and VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 + CONTROL "Install boot loader on the hard disk (VBR only)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11 + CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11 PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE PUSHBUTTON "&Cancel", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE END diff --git a/reactos/base/setup/reactos/lang/fr-FR.rc b/reactos/base/setup/reactos/lang/fr-FR.rc index 17655c95e5b..68e3cc1a41a 100644 --- a/reactos/base/setup/reactos/lang/fr-FR.rc +++ b/reactos/base/setup/reactos/lang/fr-FR.rc @@ -89,8 +89,9 @@ BEGIN CONTROL "Boot loader installation", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41 - CONTROL "Install boot loader on the hard disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 - CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11 + CONTROL "Install boot loader on the hard disk (MBR and VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 + CONTROL "Install boot loader on the hard disk (VBR only)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11 + CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11 PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE PUSHBUTTON "&Cancel", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE END diff --git a/reactos/base/setup/reactos/lang/sk-SK.rc b/reactos/base/setup/reactos/lang/sk-SK.rc index 56ff08c7e5b..6cbeb134664 100644 --- a/reactos/base/setup/reactos/lang/sk-SK.rc +++ b/reactos/base/setup/reactos/lang/sk-SK.rc @@ -1,6 +1,6 @@ /* TRANSLATOR : Mário Kačmár /Mario Kacmar/ aka Kario (kario@szm.sk) * DATE OF TR.: xx-xx-2007 - * LAST UPDATE: 03-12-2008 + * LAST UPDATE: 02-11-2010 */ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT @@ -94,8 +94,9 @@ BEGIN CONTROL "Inštalácia zavádzača systému", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41 - CONTROL "Nainštalovať zavádzač systému na pevný disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 - CONTROL "Nenainštalovať zavádzač systému", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11 + CONTROL "Nainštalovať zavádzač systému na pevný disk (MBR a VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 + CONTROL "Nainštalovať zavádzač systému na pevný disk (iba VBR)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11 + CONTROL "Nenainštalovať zavádzač systému", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11 PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE PUSHBUTTON "&Zrušiť", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE END diff --git a/reactos/base/setup/reactos/resource.h b/reactos/base/setup/reactos/resource.h index f4d6b2210bf..82e9d7c6fcd 100644 --- a/reactos/base/setup/reactos/resource.h +++ b/reactos/base/setup/reactos/resource.h @@ -31,32 +31,33 @@ #define IDC_PARTCREATE 2022 #define IDC_PARTDELETE 2023 #define IDC_INSTFREELDR 2024 -#define IDC_NOINSTFREELDR 2025 -#define IDC_PATH 2026 -#define IDD_PROCESSPAGE 2027 -#define IDS_PROCESSTITLE 2028 -#define IDS_PROCESSSUBTITLE 2029 -#define IDC_ACTIVITY 2030 -#define IDC_ITEM 2031 -#define IDC_PROCESSPROGRESS 2032 -#define IDD_RESTARTPAGE 2033 -#define IDS_RESTARTTITLE 2034 -#define IDS_RESTARTSUBTITLE 2035 -#define IDC_FINISHTITLE 2036 -#define IDC_RESTART_PROGRESS 2037 -#define IDS_ABORTSETUP 2038 -#define IDS_ABORTSETUP2 2039 -#define IDC_ACTION 2040 -#define IDC_PARTMOREOPTS 2041 -#define IDD_BOOTOPTIONS 2042 -#define IDD_PARTITION 2043 -#define IDC_UPDOWN1 2044 -#define IDC_PARTSIZE 2045 -#define IDC_UNIT 2046 -#define IDC_FSTYPE 2047 -#define IDD_SUMMARYPAGE 2048 -#define IDS_SUMMARYTITLE 2049 -#define IDS_SUMMARYSUBTITLE 2050 -#define IDC_DEVICEDRIVER 2051 +#define IDC_INSTVBRONLY 2025 +#define IDC_NOINSTFREELDR 2026 +#define IDC_PATH 2027 +#define IDD_PROCESSPAGE 2028 +#define IDS_PROCESSTITLE 2029 +#define IDS_PROCESSSUBTITLE 2030 +#define IDC_ACTIVITY 2031 +#define IDC_ITEM 2032 +#define IDC_PROCESSPROGRESS 2033 +#define IDD_RESTARTPAGE 2034 +#define IDS_RESTARTTITLE 2035 +#define IDS_RESTARTSUBTITLE 2036 +#define IDC_FINISHTITLE 2037 +#define IDC_RESTART_PROGRESS 2038 +#define IDS_ABORTSETUP 2039 +#define IDS_ABORTSETUP2 2040 +#define IDC_ACTION 2041 +#define IDC_PARTMOREOPTS 2042 +#define IDD_BOOTOPTIONS 2043 +#define IDD_PARTITION 2044 +#define IDC_UPDOWN1 2045 +#define IDC_PARTSIZE 2046 +#define IDC_UNIT 2047 +#define IDC_FSTYPE 2048 +#define IDD_SUMMARYPAGE 2049 +#define IDS_SUMMARYTITLE 2050 +#define IDS_SUMMARYSUBTITLE 2051 +#define IDC_DEVICEDRIVER 2052 #define IDI_MAIN 3000 From 10346cccb2a6a355057e88c64a23714092093b78 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 15 Mar 2011 18:56:17 +0000 Subject: [PATCH 06/90] [NTDLL/LDR] - Rewrite loader lock APIs. Now they support proper flags, return correct error codes and generate/check a cookie. svn path=/trunk/; revision=51056 --- reactos/dll/ntdll/include/ntdllp.h | 2 + reactos/dll/ntdll/ldr/ldrapi.c | 249 +++++++++++++++++++++++++++++ reactos/dll/ntdll/ldr/ldrinit.c | 2 + reactos/dll/ntdll/ldr/startup.c | 5 +- reactos/dll/ntdll/ldr/utils.c | 73 --------- reactos/dll/ntdll/ntdll.rbuild | 1 + 6 files changed, 256 insertions(+), 76 deletions(-) create mode 100644 reactos/dll/ntdll/ldr/ldrapi.c diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index 41e996c17b1..b7b20ff7f92 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -21,6 +21,8 @@ typedef BOOL ULONG ul_reason_for_call, LPVOID lpReserved); +/* Global data */ +extern RTL_CRITICAL_SECTION LdrpLoaderLock; /* ldrinit.c */ NTSTATUS NTAPI LdrpInitializeTls(VOID); diff --git a/reactos/dll/ntdll/ldr/ldrapi.c b/reactos/dll/ntdll/ldr/ldrapi.c new file mode 100644 index 00000000000..db71d74ca3c --- /dev/null +++ b/reactos/dll/ntdll/ldr/ldrapi.c @@ -0,0 +1,249 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS NT User Mode Library + * FILE: dll/ntdll/ldr/ldrapi.c + * PURPOSE: PE Loader Public APIs + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +#define LDR_LOCK_HELD 0x2 +#define LDR_LOCK_FREE 0x1 + +LONG LdrpLoaderLockAcquisitonCount; + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +LdrUnlockLoaderLock(IN ULONG Flags, + IN ULONG Cookie OPTIONAL) +{ + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("LdrUnlockLoaderLock(%x %x)\n", Flags, Cookie); + + /* Check for valid flags */ + if (Flags & ~1) + { + /* Flags are invalid, check how to fail */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + { + /* The caller wants us to raise status */ + RtlRaiseStatus(STATUS_INVALID_PARAMETER_1); + } + else + { + /* A normal failure */ + return STATUS_INVALID_PARAMETER_1; + } + } + + /* If we don't have a cookie, just return */ + if (!Cookie) return STATUS_SUCCESS; + + /* Validate the cookie */ + if ((Cookie & 0xF0000000) || + ((Cookie >> 16) ^ ((ULONG)(NtCurrentTeb()->RealClientId.UniqueThread) & 0xFFF))) + { + DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n"); + + /* Invalid cookie, check how to fail */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + { + /* The caller wants us to raise status */ + RtlRaiseStatus(STATUS_INVALID_PARAMETER_2); + } + else + { + /* A normal failure */ + return STATUS_INVALID_PARAMETER_2; + } + } + + /* Ready to release the lock */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + { + /* Do a direct leave */ + RtlLeaveCriticalSection(&LdrpLoaderLock); + } + else + { + /* Wrap this in SEH, since we're not supposed to raise */ + _SEH2_TRY + { + /* Leave the lock */ + RtlLeaveCriticalSection(&LdrpLoaderLock); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* We should use the LDR Filter instead */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + + /* All done */ + return Status; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +LdrLockLoaderLock(IN ULONG Flags, + OUT PULONG Result OPTIONAL, + OUT PULONG Cookie OPTIONAL) +{ + LONG OldCount; + NTSTATUS Status = STATUS_SUCCESS; + BOOLEAN InInit = FALSE; // FIXME + //BOOLEAN InInit = LdrpInLdrInit; + + DPRINT("LdrLockLoaderLock(%x %p %p)\n", Flags, Result, Cookie); + + /* Zero out the outputs */ + if (Result) *Result = 0; + if (Cookie) *Cookie = 0; + + /* Validate the flags */ + if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS | + LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)) + { + /* Flags are invalid, check how to fail */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + { + /* The caller wants us to raise status */ + RtlRaiseStatus(STATUS_INVALID_PARAMETER_1); + } + + /* A normal failure */ + return STATUS_INVALID_PARAMETER_1; + } + + /* Make sure we got a cookie */ + if (!Cookie) + { + /* No cookie check how to fail */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + { + /* The caller wants us to raise status */ + RtlRaiseStatus(STATUS_INVALID_PARAMETER_3); + } + + /* A normal failure */ + return STATUS_INVALID_PARAMETER_3; + } + + /* If the flag is set, make sure we have a valid pointer to use */ + if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result)) + { + /* No pointer to return the data to */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + { + /* The caller wants us to raise status */ + RtlRaiseStatus(STATUS_INVALID_PARAMETER_2); + } + + /* Fail */ + return STATUS_INVALID_PARAMETER_2; + } + + /* Return now if we are in the init phase */ + if (InInit) return STATUS_SUCCESS; + + /* Check what locking semantic to use */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + { + /* Check if we should enter or simply try */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) + { + /* Do a try */ + if (!RtlTryEnterCriticalSection(&LdrpLoaderLock)) + { + /* It's locked */ + *Result = LDR_LOCK_HELD; + goto Quickie; + } + else + { + /* It worked */ + *Result = LDR_LOCK_FREE; + } + } + else + { + /* Do a enter */ + RtlEnterCriticalSection(&LdrpLoaderLock); + + /* See if result was requested */ + if (Result) *Result = LDR_LOCK_FREE; + } + + /* Increase the acquisition count */ + OldCount = _InterlockedIncrement(&LdrpLoaderLockAcquisitonCount); + + /* Generate a cookie */ + *Cookie = (((ULONG)NtCurrentTeb()->RealClientId.UniqueThread & 0xFFF) << 16) | OldCount; + } + else + { + /* Wrap this in SEH, since we're not supposed to raise */ + _SEH2_TRY + { + /* Check if we should enter or simply try */ + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) + { + /* Do a try */ + if (!RtlTryEnterCriticalSection(&LdrpLoaderLock)) + { + /* It's locked */ + *Result = LDR_LOCK_HELD; + _SEH2_YIELD(return STATUS_SUCCESS); + } + else + { + /* It worked */ + *Result = LDR_LOCK_FREE; + } + } + else + { + /* Do an enter */ + RtlEnterCriticalSection(&LdrpLoaderLock); + + /* See if result was requested */ + if (Result) *Result = LDR_LOCK_FREE; + } + + /* Increase the acquisition count */ + OldCount = _InterlockedIncrement(&LdrpLoaderLockAcquisitonCount); + + /* Generate a cookie */ + *Cookie = (((ULONG)NtCurrentTeb()->RealClientId.UniqueThread & 0xFFF) << 16) | OldCount; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* We should use the LDR Filter instead */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + +Quickie: + return Status; +} + +/* EOF */ diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index 9d4e378d22a..72e717beb33 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -28,6 +28,8 @@ LIST_ENTRY LdrpTlsList; ULONG LdrpNumberOfTlsEntries; ULONG LdrpNumberOfProcessors; +RTL_CRITICAL_SECTION LdrpLoaderLock; + BOOLEAN ShowSnaps; /* FUNCTIONS *****************************************************************/ diff --git a/reactos/dll/ntdll/ldr/startup.c b/reactos/dll/ntdll/ldr/startup.c index 06b90b07558..fb814c499f2 100644 --- a/reactos/dll/ntdll/ldr/startup.c +++ b/reactos/dll/ntdll/ldr/startup.c @@ -25,7 +25,6 @@ extern PTEB LdrpTopLevelDllBeingLoadedTeb; PLDR_DATA_TABLE_ENTRY ExeModule; static RTL_CRITICAL_SECTION PebLock; -static RTL_CRITICAL_SECTION LoaderLock; static RTL_BITMAP TlsBitMap; static RTL_BITMAP TlsExpansionBitMap; static volatile BOOLEAN LdrpInitialized = FALSE; @@ -467,8 +466,8 @@ LdrpInit2(PCONTEXT Context, } /* initalize loader lock */ - RtlInitializeCriticalSection(&LoaderLock); - Peb->LoaderLock = &LoaderLock; + RtlInitializeCriticalSection(&LdrpLoaderLock); + Peb->LoaderLock = &LdrpLoaderLock; /* create loader information */ Peb->Ldr = (PPEB_LDR_DATA) RtlAllocateHeap(Peb->ProcessHeap, diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 41c2802cafb..cd7c7d69023 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -3154,79 +3154,6 @@ LdrProcessRelocationBlock( return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta); } -NTSTATUS -NTAPI -LdrLockLoaderLock(IN ULONG Flags, - OUT PULONG Disposition OPTIONAL, - OUT PULONG Cookie OPTIONAL) -{ - NTSTATUS Status; - BOOLEAN Ret; - BOOLEAN CookieSet = FALSE; - - if ((Flags != 0x01) && (Flags != 0x02)) - return STATUS_INVALID_PARAMETER_1; - - if (!Cookie) return STATUS_INVALID_PARAMETER_3; - - /* Set some defaults for failure while verifying params */ - _SEH2_TRY - { - *Cookie = 0; - CookieSet = TRUE; - if (Disposition) *Disposition = 0; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - if (CookieSet) - Status = STATUS_INVALID_PARAMETER_3; - else - Status = STATUS_INVALID_PARAMETER_2; - } - _SEH2_END; - - if (Flags == 0x01) - { - DPRINT1("Warning: Reporting errors with exception not supported yet!\n"); - RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); - Status = STATUS_SUCCESS; - - } - else - { - if (!Disposition) return STATUS_INVALID_PARAMETER_2; - - Ret = RtlTryEnterCriticalSection(NtCurrentPeb()->LoaderLock); - - if (Ret) - *Disposition = 0x01; - else - *Disposition = 0x02; - - Status = STATUS_SUCCESS; - } - - /* FIXME: Cookie is based on part of the thread id */ - *Cookie = (ULONG)NtCurrentTeb()->RealClientId.UniqueThread; - return Status; -} - -NTSTATUS -NTAPI -LdrUnlockLoaderLock(IN ULONG Flags, - IN ULONG Cookie OPTIONAL) -{ - if (Flags != 0x01) - return STATUS_INVALID_PARAMETER_1; - - if (Cookie != (ULONG)NtCurrentTeb()->RealClientId.UniqueThread) - return STATUS_INVALID_PARAMETER_2; - - RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); - - return STATUS_SUCCESS; -} - BOOLEAN NTAPI LdrUnloadAlternateResourceModule(IN PVOID BaseAddress) diff --git a/reactos/dll/ntdll/ntdll.rbuild b/reactos/dll/ntdll/ntdll.rbuild index 0a319e5603e..544a53b67ea 100644 --- a/reactos/dll/ntdll/ntdll.rbuild +++ b/reactos/dll/ntdll/ntdll.rbuild @@ -47,6 +47,7 @@ ntdll.h + ldrapi.c ldrinit.c ldrutils.c startup.c From c6add84fb917f2fc941602a1d640a04ae39d9c27 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Tue, 15 Mar 2011 19:45:43 +0000 Subject: [PATCH 07/90] [NDK] Define HAL_IRQ_TRANSLATOR_VERSION constant [NTOSKRNL] When needed, use HAL_IRQ_TRANSLATOR_VERSION from NDK and don't define it locally svn path=/trunk/; revision=51057 --- reactos/include/ndk/haltypes.h | 5 +++++ reactos/ntoskrnl/fstub/translate.c | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/reactos/include/ndk/haltypes.h b/reactos/include/ndk/haltypes.h index 272a0d4fdc2..904a83146f1 100644 --- a/reactos/include/ndk/haltypes.h +++ b/reactos/include/ndk/haltypes.h @@ -270,6 +270,11 @@ extern NTSYSAPI HAL_PRIVATE_DISPATCH HalPrivateDispatchTable; // extern PUCHAR NTHALAPI KdComPortInUse; +// +// HAL Constants +// +#define HAL_IRQ_TRANSLATOR_VERSION 0x0 + #endif #endif diff --git a/reactos/ntoskrnl/fstub/translate.c b/reactos/ntoskrnl/fstub/translate.c index b9d37d266cd..839e6f01488 100644 --- a/reactos/ntoskrnl/fstub/translate.c +++ b/reactos/ntoskrnl/fstub/translate.c @@ -12,8 +12,6 @@ #define NDEBUG #include -#define HAL_IRQ_TRANSLATOR_VERSION 0x0 - /* PRIVATE FUNCTIONS *********************************************************/ /* From 7ffb757e8bca5d6508919b2a864a93b87c921f27 Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Tue, 15 Mar 2011 23:45:38 +0000 Subject: [PATCH 08/90] [CRT] - Revert 38185 which synced fputwc to the Wine version for the sake of fixing Winetests. This removed the implicit ANSI conversion, which was honestly checking the wrong flags. The new version correctly checks for WX_TEXT and only does the conversion in this case. This way we also don't fail any additional Winetests. - Simplify streamout_char in the new printf implementation and use _fputtc instead of _flsbuf. This way, we correctly do an implicit ANSI conversion when required. - Fix fgetwc declaration. Thanks to Timo for many hints and assistance. Most of this code is actually his idea :-) Thanks to Olaf for providing a build server to speed up my code tests. See issue #6007 for more details. svn path=/trunk/; revision=51058 --- reactos/lib/sdk/crt/printf/streamout.c | 23 +++++-------------- reactos/lib/sdk/crt/stdio/file.c | 31 +++++++++++++++++++++----- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/reactos/lib/sdk/crt/printf/streamout.c b/reactos/lib/sdk/crt/printf/streamout.c index 8e9ce4f667a..66aae271dd5 100644 --- a/reactos/lib/sdk/crt/printf/streamout.c +++ b/reactos/lib/sdk/crt/printf/streamout.c @@ -16,13 +16,6 @@ #ifdef _UNICODE # define streamout wstreamout # define format_float format_floatw -# define _flsbuf _flswbuf -int __cdecl _flswbuf(int ch, FILE *stream); -#endif - -#ifdef _LIBCNT_ -# undef _flsbuf -# define _flsbuf(chr, stream) _TEOF #endif #define MB_CUR_MAX 10 @@ -234,25 +227,19 @@ static int streamout_char(FILE *stream, int chr) { +#if defined(_USER32_WSPRINTF) || defined(_LIBCNT_) /* Check if the buffer is full */ if (stream->_cnt < sizeof(TCHAR)) - { -#ifdef _USER32_WSPRINTF - return _TEOF; -#else - /* Strings are done now */ - if (stream->_flag & _IOSTRG) return _TEOF; - - /* Flush buffer for files */ - return _flsbuf(chr, stream) != _TEOF; -#endif - } + return 0; *(TCHAR*)stream->_ptr = chr; stream->_ptr += sizeof(TCHAR); stream->_cnt -= sizeof(TCHAR); return 1; +#else + return _fputtc((TCHAR)chr, stream) != _TEOF; +#endif } static diff --git a/reactos/lib/sdk/crt/stdio/file.c b/reactos/lib/sdk/crt/stdio/file.c index a66da9de9d4..cb5f5ae3dd8 100644 --- a/reactos/lib/sdk/crt/stdio/file.c +++ b/reactos/lib/sdk/crt/stdio/file.c @@ -2175,12 +2175,33 @@ size_t CDECL fwrite(const void *ptr, size_t size, size_t nmemb, FILE* file) /********************************************************************* * fputwc (MSVCRT.@) */ -wint_t CDECL fputwc(wint_t wc, FILE* file) +wint_t CDECL fputwc(wchar_t c, FILE* stream) { - wchar_t mwc=wc; - if (fwrite( &mwc, sizeof(mwc), 1, file) != 1) - return WEOF; - return wc; + /* If this is a real file stream (and not some temporary one for + sprintf-like functions), check whether it is opened in text mode. + In this case, we have to perform an implicit conversion to ANSI. */ + if (!(stream->_flag & _IOSTRG) && fdesc[stream->_file].wxflag & WX_TEXT) + { + /* Convert to multibyte in text mode */ + char mbc[MB_LEN_MAX]; + int mb_return; + + mb_return = wctomb(mbc, c); + + if(mb_return == -1) + return WEOF; + + /* Output all characters */ + if (fwrite(mbc, mb_return, 1, stream) != 1) + return WEOF; + } + else + { + if (fwrite(&c, sizeof(c), 1, stream) != 1) + return WEOF; + } + + return c; } /********************************************************************* From c396511623cea225674c950f1e3e116cf7dc2188 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 16 Mar 2011 09:49:07 +0000 Subject: [PATCH 09/90] [RTL] - Implement LdrVerifyMappedImageChecksum (copied from ntdll/ldr/utils.c). svn path=/trunk/; revision=51059 --- reactos/lib/rtl/image.c | 73 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index 3886fb5ac5e..479319f5fef 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -24,11 +24,78 @@ BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum( IN PVOID BaseAddress, - IN ULONG NumberOfBytes, + IN ULONG ImageSize, IN ULONG FileLength) { - /* FIXME: TODO */ - return TRUE; + PIMAGE_NT_HEADERS Header; + PUSHORT Ptr; + ULONG Sum; + ULONG CalcSum; + ULONG HeaderSum; + ULONG i; + + /* Get NT header to check if it's an image at all */ + Header = RtlImageNtHeader (BaseAddress); + if (!Header) return FALSE; + + /* Get checksum to match */ + HeaderSum = Header->OptionalHeader.CheckSum; + + /* Zero checksum seems to be accepted */ + if (HeaderSum == 0) return TRUE; + + /* Calculate the checksum */ + Sum = 0; + Ptr = (PUSHORT) BaseAddress; + for (i = 0; i < ImageSize / sizeof (USHORT); i++) + { + Sum += (ULONG)*Ptr; + if (HIWORD(Sum) != 0) + { + Sum = LOWORD(Sum) + HIWORD(Sum); + } + Ptr++; + } + + if (ImageSize & 1) + { + Sum += (ULONG)*((PUCHAR)Ptr); + if (HIWORD(Sum) != 0) + { + Sum = LOWORD(Sum) + HIWORD(Sum); + } + } + + CalcSum = (USHORT)(LOWORD(Sum) + HIWORD(Sum)); + + /* Subtract image checksum from calculated checksum. */ + /* fix low word of checksum */ + if (LOWORD(CalcSum) >= LOWORD(HeaderSum)) + { + CalcSum -= LOWORD(HeaderSum); + } + else + { + CalcSum = ((LOWORD(CalcSum) - LOWORD(HeaderSum)) & 0xFFFF) - 1; + } + + /* Fix high word of checksum */ + if (LOWORD(CalcSum) >= HIWORD(HeaderSum)) + { + CalcSum -= HIWORD(HeaderSum); + } + else + { + CalcSum = ((LOWORD(CalcSum) - HIWORD(HeaderSum)) & 0xFFFF) - 1; + } + + /* Add file length */ + CalcSum += ImageSize; + + if (CalcSum != HeaderSum) + DPRINT1("Image %p checksum mismatches! 0x%x != 0x%x\n", BaseAddress, CalcSum, HeaderSum); + + return (BOOLEAN)(CalcSum == HeaderSum); } /* From cfec4ed82617aa194665683ee3bc904831cf2a00 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 16 Mar 2011 09:52:41 +0000 Subject: [PATCH 10/90] [NTDLL/LDR] - Rewrite LdrImageMatchesChecksum, remove now outdated LdrpCheckImageChecksum. svn path=/trunk/; revision=51060 --- reactos/dll/ntdll/ldr/ldrapi.c | 132 ++++++++++++++++++++++++++ reactos/dll/ntdll/ldr/utils.c | 164 --------------------------------- 2 files changed, 132 insertions(+), 164 deletions(-) diff --git a/reactos/dll/ntdll/ldr/ldrapi.c b/reactos/dll/ntdll/ldr/ldrapi.c index db71d74ca3c..55e1582a446 100644 --- a/reactos/dll/ntdll/ldr/ldrapi.c +++ b/reactos/dll/ntdll/ldr/ldrapi.c @@ -246,4 +246,136 @@ Quickie: return Status; } +/* + * @implemented + */ +NTSTATUS +NTAPI +LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle, + IN PLDR_CALLBACK Callback, + IN PVOID CallbackContext, + OUT PUSHORT ImageCharacteristics) +{ + FILE_STANDARD_INFORMATION FileStandardInfo; + PIMAGE_IMPORT_DESCRIPTOR ImportData; + PIMAGE_SECTION_HEADER LastSection; + IO_STATUS_BLOCK IoStatusBlock; + PIMAGE_NT_HEADERS NtHeader; + HANDLE SectionHandle; + SIZE_T ViewSize = 0; + PVOID ViewBase = NULL; + BOOLEAN Result; + NTSTATUS Status; + PVOID ImportName; + ULONG Size; + + DPRINT("LdrVerifyImageMatchesChecksum() called\n"); + + /* Create the section */ + Status = NtCreateSection(&SectionHandle, + SECTION_MAP_EXECUTE, + NULL, + NULL, + PAGE_EXECUTE, + SEC_COMMIT, + FileHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("NtCreateSection() failed (Status 0x%x)\n", Status); + return Status; + } + + /* Map the section */ + Status = NtMapViewOfSection(SectionHandle, + NtCurrentProcess(), + &ViewBase, + 0, + 0, + NULL, + &ViewSize, + ViewShare, + 0, + PAGE_EXECUTE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status); + NtClose(SectionHandle); + return Status; + } + + /* Get the file information */ + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileStandardInfo, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status); + NtUnmapViewOfSection(NtCurrentProcess(), ViewBase); + NtClose(SectionHandle); + return Status; + } + + /* Protect with SEH */ + _SEH2_TRY + { + /* Verify the checksum */ + Result = LdrVerifyMappedImageMatchesChecksum(ViewBase, + ViewSize, + FileStandardInfo.EndOfFile.LowPart); + + /* Check if a callback was supplied */ + if (Result && Callback) + { + /* Get the NT Header */ + NtHeader = RtlImageNtHeader(ViewBase); + + /* Check if caller requested this back */ + if (ImageCharacteristics) + { + /* Return to caller */ + *ImageCharacteristics = NtHeader->FileHeader.Characteristics; + } + + /* Get the Import Directory Data */ + ImportData = RtlImageDirectoryEntryToData(ViewBase, + FALSE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + + /* Make sure there is one */ + if (ImportData) + { + /* Loop the imports */ + while (ImportData->Name) + { + /* Get the name */ + ImportName = RtlImageRvaToVa(NtHeader, + ViewBase, + ImportData->Name, + &LastSection); + + /* Notify the callback */ + Callback(CallbackContext, ImportName); + ImportData++; + } + } + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail the request returning STATUS_IMAGE_CHECKSUM_MISMATCH */ + Result = FALSE; + } + _SEH2_END; + + /* Unmap file and close handle */ + NtUnmapViewOfSection(NtCurrentProcess(), ViewBase); + NtClose(SectionHandle); + + /* Return status */ + return !Result ? STATUS_IMAGE_CHECKSUM_MISMATCH : Status; +} + /* EOF */ diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index cd7c7d69023..e03cb12a3d2 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -2950,76 +2950,6 @@ LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIO return(Status); } - -static BOOLEAN -LdrpCheckImageChecksum (IN PVOID BaseAddress, - IN ULONG ImageSize) -{ - PIMAGE_NT_HEADERS Header; - PUSHORT Ptr; - ULONG Sum; - ULONG CalcSum; - ULONG HeaderSum; - ULONG i; - - Header = RtlImageNtHeader (BaseAddress); - if (Header == NULL) - return FALSE; - - HeaderSum = Header->OptionalHeader.CheckSum; - if (HeaderSum == 0) - return TRUE; - - Sum = 0; - Ptr = (PUSHORT) BaseAddress; - for (i = 0; i < ImageSize / sizeof (USHORT); i++) - { - Sum += (ULONG)*Ptr; - if (HIWORD(Sum) != 0) - { - Sum = LOWORD(Sum) + HIWORD(Sum); - } - Ptr++; - } - - if (ImageSize & 1) - { - Sum += (ULONG)*((PUCHAR)Ptr); - if (HIWORD(Sum) != 0) - { - Sum = LOWORD(Sum) + HIWORD(Sum); - } - } - - CalcSum = (USHORT)(LOWORD(Sum) + HIWORD(Sum)); - - /* Subtract image checksum from calculated checksum. */ - /* fix low word of checksum */ - if (LOWORD(CalcSum) >= LOWORD(HeaderSum)) - { - CalcSum -= LOWORD(HeaderSum); - } - else - { - CalcSum = ((LOWORD(CalcSum) - LOWORD(HeaderSum)) & 0xFFFF) - 1; - } - - /* fix high word of checksum */ - if (LOWORD(CalcSum) >= HIWORD(HeaderSum)) - { - CalcSum -= HIWORD(HeaderSum); - } - else - { - CalcSum = ((LOWORD(CalcSum) - HIWORD(HeaderSum)) & 0xFFFF) - 1; - } - - /* add file length */ - CalcSum += ImageSize; - - return (BOOLEAN)(CalcSum == HeaderSum); -} - /* * Compute size of an image as it is actually present in virt memory * (i.e. excluding NEVER_LOAD sections) @@ -3049,100 +2979,6 @@ LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders) return ResidentSize; } - -/*************************************************************************** - * NAME EXPORTED - * LdrVerifyImageMatchesChecksum - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - * NOTE - * - * @implemented - */ -NTSTATUS NTAPI -LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle, - IN PLDR_CALLBACK Callback, - IN PVOID CallbackContext, - OUT PUSHORT ImageCharacterstics) -{ - FILE_STANDARD_INFORMATION FileInfo; - IO_STATUS_BLOCK IoStatusBlock; - HANDLE SectionHandle; - SIZE_T ViewSize; - PVOID BaseAddress; - BOOLEAN Result; - NTSTATUS Status; - - DPRINT ("LdrVerifyImageMatchesChecksum() called\n"); - - Status = NtCreateSection (&SectionHandle, - SECTION_MAP_READ, - NULL, - NULL, - PAGE_READONLY, - SEC_COMMIT, - FileHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("NtCreateSection() failed (Status %lx)\n", Status); - return Status; - } - - ViewSize = 0; - BaseAddress = NULL; - Status = NtMapViewOfSection (SectionHandle, - NtCurrentProcess (), - &BaseAddress, - 0, - 0, - NULL, - &ViewSize, - ViewShare, - 0, - PAGE_READONLY); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status); - NtClose (SectionHandle); - return Status; - } - - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof (FILE_STANDARD_INFORMATION), - FileStandardInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status); - NtUnmapViewOfSection (NtCurrentProcess(), - BaseAddress); - NtClose (SectionHandle); - return Status; - } - - Result = LdrpCheckImageChecksum(BaseAddress, - FileInfo.EndOfFile.u.LowPart); - if (Result == FALSE) - { - Status = STATUS_IMAGE_CHECKSUM_MISMATCH; - } - - NtUnmapViewOfSection (NtCurrentProcess(), - BaseAddress); - - NtClose(SectionHandle); - - return Status; -} - PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlock( From 8f7c38cd4477370a9ecbf77d95ebec3c720cf123 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 16 Mar 2011 11:58:12 +0000 Subject: [PATCH 11/90] [RTL] - Hack away LdrVerifyMappedImageMatchesChecksum() invocations with zero ImageSize until MM is fixed. - Implement a helper ChkSum() routine to be used later by LdrVerifyMappedImageMatchesChecksum(). svn path=/trunk/; revision=51061 --- reactos/lib/rtl/image.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index 479319f5fef..03c402fc20c 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -20,6 +20,25 @@ /* FUNCTIONS *****************************************************************/ +USHORT +FORCEINLINE +ChkSum(ULONG Sum, PUSHORT Src, ULONG Len) +{ + ULONG i; + + for (i=0; i> 16); + } + + /* Apply carry one more time and clamp to the USHORT */ + return (Sum + (Sum >> 16)) & 0xFFFF; +} + BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum( @@ -34,8 +53,11 @@ LdrVerifyMappedImageMatchesChecksum( ULONG HeaderSum; ULONG i; + // HACK: Ignore calls with ImageSize=0. Should be fixed by new MM. + if (ImageSize == 0) return TRUE; + /* Get NT header to check if it's an image at all */ - Header = RtlImageNtHeader (BaseAddress); + Header = RtlImageNtHeader(BaseAddress); if (!Header) return FALSE; /* Get checksum to match */ @@ -93,7 +115,7 @@ LdrVerifyMappedImageMatchesChecksum( CalcSum += ImageSize; if (CalcSum != HeaderSum) - DPRINT1("Image %p checksum mismatches! 0x%x != 0x%x\n", BaseAddress, CalcSum, HeaderSum); + DPRINT1("Image %p checksum mismatches! 0x%x != 0x%x, ImageSize %x, FileLen %x\n", BaseAddress, CalcSum, HeaderSum, ImageSize, FileLength); return (BOOLEAN)(CalcSum == HeaderSum); } From d1b85c4a85fab89eac05f617220ab067696ed8a7 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 16 Mar 2011 12:18:57 +0000 Subject: [PATCH 12/90] [RAPPS] Due to a lack of implemented feature in DLL, switch FF3.6 download links to HTTP. Site given by Mozilla Foundation. svn path=/trunk/; revision=51062 --- .../base/applications/rapps/rapps/firefox36.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reactos/base/applications/rapps/rapps/firefox36.txt b/reactos/base/applications/rapps/rapps/firefox36.txt index d8a96e71e56..4f5d3b8c96b 100644 --- a/reactos/base/applications/rapps/rapps/firefox36.txt +++ b/reactos/base/applications/rapps/rapps/firefox36.txt @@ -8,47 +8,47 @@ Description = The most popular and one of the best free Web Browsers out there. Size = 8.2M Category = 5 URLSite = http://www.mozilla.com/en-US/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/en-US/Firefox%20Setup%203.6.15.exe +URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/en-US/Firefox%20Setup%203.6.15.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Webbrowser. Size = 8.1M URLSite = http://www.mozilla-europe.org/de/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/de/Firefox%20Setup%203.6.15.exe +URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/de/Firefox%20Setup%203.6.15.exe [Section.040a] Description = El más popular y uno de los mejores navegadores web gratuitos que hay. Size = 8.1M URLSite = http://www.mozilla-europe.org/es/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/es-ES/Firefox%20Setup%203.6.15.exe +URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/es-ES/Firefox%20Setup%203.6.15.exe [Section.040c] Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs. Size = 8.1M URLSite = http://www.mozilla-europe.org/fr/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/fr/Firefox%20Setup%203.6.15.exe +URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/fr/Firefox%20Setup%203.6.15.exe [Section.0414] Description = Mest populære og best ogsĂĄ gratis nettleserene der ute. Size = 8.1M URLSite = http://www.mozilla-europe.org/no/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/nb-NO/Firefox%20Setup%203.6.15.exe +URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/nb-NO/Firefox%20Setup%203.6.15.exe [Section.0415] Description = Najpopularniejsza i jedna z najlepszych darmowych przeglÄ…darek internetowych. Size = 8.9M URLSite = http://www.mozilla-europe.org/pl/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/pl/Firefox%20Setup%203.6.15.exe +URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/pl/Firefox%20Setup%203.6.15.exe [Section.0419] Description = Один из Ńамых попŃлярных и Đ»ŃчŃих беŃплатных браŃзеров. Size = 8.5M URLSite = http://www.mozilla-europe.org/ru/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/ru/Firefox%20Setup%203.6.15.exe +URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/ru/Firefox%20Setup%203.6.15.exe [Section.0422] Description = НайпопŃлярніŃий та один Đ· кращих безплатних веб-браŃзерів. Size = 8.5M URLSite = http://www.mozilla-europe.org/uk/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/uk/Firefox%20Setup%203.6.15.exe +URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/uk/Firefox%20Setup%203.6.15.exe From 4b2c1d1a6bfe62b5292a88299cfe50b4ce65a756 Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Wed, 16 Mar 2011 13:28:39 +0000 Subject: [PATCH 13/90] [RAPPS] Change all ftp:// links to http:// ones. The changes to the fragile Mozilla links should be reverted as soon as our/Wine's URLDownloadToFileW function finally supports FTP URLs. Vote for Wine Bug 26445 (http://bugs.winehq.org/show_bug.cgi?id=26445) to get this fixed! svn path=/trunk/; revision=51063 --- reactos/base/applications/rapps/rapps/firefox2.txt | 10 +--------- reactos/base/applications/rapps/rapps/firefox3.txt | 10 +--------- .../applications/rapps/rapps/openoffice2.4.txt | 12 ++++++------ .../base/applications/rapps/rapps/seamonkey.txt | 12 ++++++------ .../base/applications/rapps/rapps/thunderbird.txt | 14 +++++++------- reactos/base/applications/rapps/rapps/winboard.txt | 2 +- 6 files changed, 22 insertions(+), 38 deletions(-) diff --git a/reactos/base/applications/rapps/rapps/firefox2.txt b/reactos/base/applications/rapps/rapps/firefox2.txt index 816bf597e62..efb7f8b514c 100644 --- a/reactos/base/applications/rapps/rapps/firefox2.txt +++ b/reactos/base/applications/rapps/rapps/firefox2.txt @@ -8,45 +8,37 @@ Description = The most popular and one of the best free Web Browsers out there. Size = 5.8M Category = 5 URLSite = http://www.mozilla.com/en-US/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/en-US/Firefox%20Setup%202.0.0.20.exe +URLDownload = http://svn.reactos.org/packages/Firefox%20Setup%202.0.0.20.exe CDPath = none [Section.0405] Description = NejpopulárnÄ›jší a jeden z nejlepších svobodnĂ˝ch webovĂ˝ch prohlĂ­ĹľeÄŤĹŻ. URLSite = http://www.mozilla-europe.org/cs/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/cs/Firefox%20Setup%202.0.0.20.exe [Section.0407] Description = Der populärste und einer der besten freien Webbrowser. URLSite = http://www.mozilla-europe.org/de/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/de/Firefox%20Setup%202.0.0.20.exe [Section.040a] Description = El más popular y uno de los mejores navegadores web gratuitos que hay. URLSite = http://www.mozilla-europe.org/es/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/es-ES/Firefox%20Setup%202.0.0.20.exe [Section.040c] Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs. URLSite = http://www.mozilla-europe.org/fr/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/fr/Firefox%20Setup%202.0.0.20.exe [Section.0414] Description = Mest populære og best ogsĂĄ gratis nettleserene der ute. URLSite = http://www.mozilla-europe.org/no/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/nb-NO/Firefox%20Setup%202.0.0.20.exe [Section.0415] Description = Najpopularniejsza i jedna z najlepszych darmowych przeglÄ…darek internetowych. URLSite = http://www.mozilla-europe.org/pl/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/pl/Firefox%20Setup%202.0.0.20.exe [Section.0419] Description = Один из Ńамых попŃлярных и Đ»ŃчŃих беŃплатных браŃзеров. URLSite = http://www.mozilla-europe.org/ru/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/ru/Firefox%20Setup%202.0.0.20.exe [Section.0422] Description = НайпопŃлярніŃий та один Đ· кращих безплатних веб-браŃзерів. URLSite = http://www.mozilla-europe.org/uk/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/uk/Firefox%20Setup%202.0.0.20.exe diff --git a/reactos/base/applications/rapps/rapps/firefox3.txt b/reactos/base/applications/rapps/rapps/firefox3.txt index 76855309d81..065202dd921 100644 --- a/reactos/base/applications/rapps/rapps/firefox3.txt +++ b/reactos/base/applications/rapps/rapps/firefox3.txt @@ -8,52 +8,44 @@ Description = The most popular and one of the best free Web Browsers out there. Size = 7.2M Category = 5 URLSite = http://www.mozilla.com/en-US/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/en-US/Firefox%20Setup%203.0.19.exe +URLDownload = http://svn.reactos.org/packages/Firefox%20Setup%203.0.19.exe CDPath = none [Section.0405] Description = NejpopulárnÄ›jší a jeden z nejlepších svobodnĂ˝ch webovĂ˝ch prohlĂ­ĹľeÄŤĹŻ. Size = 7.0M URLSite = http://www.mozilla-europe.org/cs/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/cs/Firefox%20Setup%203.0.19.exe [Section.0407] Description = Der populärste und einer der besten freien Webbrowser. Size = 7.0M URLSite = http://www.mozilla-europe.org/de/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/de/Firefox%20Setup%203.0.19.exe [Section.040a] Description = El más popular y uno de los mejores navegadores web gratuitos que hay. Size = 7.0M URLSite = http://www.mozilla-europe.org/es/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/es-ES/Firefox%20Setup%203.0.19.exe [Section.040c] Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs. URLSite = http://www.mozilla-europe.org/fr/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/fr/Firefox%20Setup%203.0.19.exe [Section.0414] Description = Mest populære og best ogsĂĄ gratis nettleserene der ute. Size = 7.0M URLSite = http://www.mozilla-europe.org/no/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/nb-NO/Firefox%20Setup%203.0.19.exe [Section.0415] Description = Najpopularniejsza i jedna z najlepszych darmowych przeglÄ…darek internetowych. Size = 7.9M URLSite = http://www.mozilla-europe.org/pl/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/pl/Firefox%20Setup%203.0.19.exe [Section.0419] Description = Один из Ńамых попŃлярных и Đ»ŃчŃих беŃплатных браŃзеров. Size = 7.8M URLSite = http://www.mozilla-europe.org/ru/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/ru/Firefox%20Setup%203.0.19.exe [Section.0422] Description = НайпопŃлярніŃий та один Đ· кращих безплатних веб-браŃзерів. Size = 7.4M URLSite = http://www.mozilla-europe.org/uk/ -URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/uk/Firefox%20Setup%203.0.19.exe diff --git a/reactos/base/applications/rapps/rapps/openoffice2.4.txt b/reactos/base/applications/rapps/rapps/openoffice2.4.txt index f2bc9ec0578..907712013be 100644 --- a/reactos/base/applications/rapps/rapps/openoffice2.4.txt +++ b/reactos/base/applications/rapps/rapps/openoffice2.4.txt @@ -8,36 +8,36 @@ Description = THE Open Source Office Suite. Size = 127MB Category = 6 URLSite = http://www.openoffice.org/ -URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/stable/2.4.3/OOo_2.4.3_Win32Intel_install_en-US.exe +URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/stable/2.4.3/OOo_2.4.3_Win32Intel_install_en-US.exe CDPath = none [Section.0407] Description = DIE Open Source Office Suite. URLSite = http://de.openoffice.org/ Size = 114.2MB -URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/de/2.4.3/OOo_2.4.3_Win32Intel_install_de.exe +URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/de/2.4.3/OOo_2.4.3_Win32Intel_install_de.exe [Section.040a] Description = La suite de ofimática de cĂłdigo abierto. URLSite = http://es.openoffice.org/ Size = 113.9MB -URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/es/2.4.3/OOo_2.4.3_Win32Intel_install_es.exe +URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/es/2.4.3/OOo_2.4.3_Win32Intel_install_es.exe [Section.040c] Version = 2.4.2 Description = LA suite bureautique open source. URLSite = http://fr.openoffice.org/ Size = 113.9MB -URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/fr/2.4.2/OOo_2.4.2_Win32Intel_install_fr.exe +URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/fr/2.4.2/OOo_2.4.2_Win32Intel_install_fr.exe [Section.0415] URLSite = http://pl.openoffice.org/ Description = Otwarty pakiet biurowy. -URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/pl/2.4.2/OOo_2.4.2_Win32Intel_install_pl.exe +URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/pl/2.4.2/OOo_2.4.2_Win32Intel_install_pl.exe Size = 113.9M [Section.0422] URLSite = http://ua.openoffice.org/ Description = Відкритий офіŃний пакет. -URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/ru/2.4.3/OOo_2.4.3_Win32Intel_install_ru.exe +URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/ru/2.4.3/OOo_2.4.3_Win32Intel_install_ru.exe Size = 114.8M diff --git a/reactos/base/applications/rapps/rapps/seamonkey.txt b/reactos/base/applications/rapps/rapps/seamonkey.txt index 82e5a0401ff..2564895cac8 100644 --- a/reactos/base/applications/rapps/rapps/seamonkey.txt +++ b/reactos/base/applications/rapps/rapps/seamonkey.txt @@ -8,30 +8,30 @@ Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Ch Size = 10.2MB Category = 5 URLSite = http://www.seamonkey-project.org/ -URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/en-US/SeaMonkey%20Setup%202.0.12.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/en-US/SeaMonkey%20Setup%202.0.12.exe CDPath = none [Section.0407] Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen. Size = 10.1MB -URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/de/SeaMonkey%20Setup%202.0.12.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/de/SeaMonkey%20Setup%202.0.12.exe [Section.040a] Description = La suite de Mozilla está viva. Es el primero y Ăşnico navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás. Size = 10.1MB -URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/es-ES/SeaMonkey%20Setup%202.0.12.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/es-ES/SeaMonkey%20Setup%202.0.12.exe [Section.040c] Description = La suite Mozilla est en vie. Ceci est le seul et l'unique package navigateur, client mail, client chat et composer dont vous aurez besoin. Size = 10.1MB -URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/fr/SeaMonkey%20Setup%202.0.12.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/fr/SeaMonkey%20Setup%202.0.12.exe [Section.0415] Description = Pakiet Mozilla ĹĽyje. W zestawie: przeglÄ…darka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz. Size = 11.0MB -URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/pl/SeaMonkey%20Setup%202.0.12.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/pl/SeaMonkey%20Setup%202.0.12.exe [Section.0419] Description = Продолжение Mozilla Suite. Включает браŃзер, почтовый клиент, IRC-клиент и HTML-редактор. Size = 10.5MB -URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/ru/SeaMonkey%20Setup%202.0.12.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/ru/SeaMonkey%20Setup%202.0.12.exe diff --git a/reactos/base/applications/rapps/rapps/thunderbird.txt b/reactos/base/applications/rapps/rapps/thunderbird.txt index 644933e5867..e91eb6c7182 100644 --- a/reactos/base/applications/rapps/rapps/thunderbird.txt +++ b/reactos/base/applications/rapps/rapps/thunderbird.txt @@ -8,41 +8,41 @@ Description = The most popular and one of the best free Mail Clients out there. Size = 9.0M Category = 5 URLSite = http://www.mozilla-europe.org/en/products/thunderbird/ -URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/en-US/Thunderbird%20Setup%203.1.9.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/en-US/Thunderbird%20Setup%203.1.9.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Mail-Clients. Size = 8.8M URLSite = http://www.mozilla-europe.org/de/products/thunderbird/ -URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/de/Thunderbird%20Setup%203.1.9.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/de/Thunderbird%20Setup%203.1.9.exe [Section.040a] Description = El más popular y uno de los mejores clientes mail que hay. Size = 8.8M URLSite = http://www.mozilla-europe.org/es/products/thunderbird/ -URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/es-ES/Thunderbird%20Setup%203.1.9.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/es-ES/Thunderbird%20Setup%203.1.9.exe [Section.040c] Description = Le plus populaire et l'un des meilleurs clients mail gratuits disponible. Size = 8.8M URLSite = http://www.mozilla-europe.org/fr/products/thunderbird/ -URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/fr/Thunderbird%20Setup%203.1.9.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/fr/Thunderbird%20Setup%203.1.9.exe [Section.0415] Description = Najpopularniejszy i jeden z najlepszych darmowych klientĂłw poczty. Size = 9.7M URLSite = http://www.mozilla-europe.org/pl/products/thunderbird/ -URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/pl/Thunderbird%20Setup%203.1.9.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/pl/Thunderbird%20Setup%203.1.9.exe [Section.0419] Description = Один из Ńамых попŃлярных и Đ»ŃчŃих беŃплатных почтовых клиентов. Size = 9.2M URLSite = http://www.mozilla-europe.org/ru/products/thunderbird/ -URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/ru/Thunderbird%20Setup%203.1.9.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/ru/Thunderbird%20Setup%203.1.9.exe [Section.0422] Description = НайпопŃлярніŃий та один Đ· кращих поŃтових клієнтів. Size = 9.2M URLSite = http://www.mozillamessaging.com/uk/thunderbird/ -URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/uk/Thunderbird%20Setup%203.1.9.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/uk/Thunderbird%20Setup%203.1.9.exe diff --git a/reactos/base/applications/rapps/rapps/winboard.txt b/reactos/base/applications/rapps/rapps/winboard.txt index 9e58a153fd0..a7a0db6ffb5 100644 --- a/reactos/base/applications/rapps/rapps/winboard.txt +++ b/reactos/base/applications/rapps/rapps/winboard.txt @@ -8,7 +8,7 @@ Description = WinBoard is a graphical chessboard for the Windows/ReactOS that ca Size = 5.9MB Category = 4 URLSite = http://www.gnu.org/software/xboard/ -URLDownload = ftp://ftp.gnu.org/old-gnu/xboard/winboard/winboard-4_2_7b.exe +URLDownload = http://ftp.gnu.org/old-gnu/xboard/winboard/winboard-4_2_7b.exe CDPath = none [Section.0407] From 3f20ae61b851d731ade24d690e46d30a7e2e6187 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 16 Mar 2011 14:22:15 +0000 Subject: [PATCH 14/90] [NTDLL/LDR] - Rewrite LdrQueryProcessModuleInformation. - Start committing PE loader related code (quite a lot of it, and still not all parts yet), unused right now so won't break anything. svn path=/trunk/; revision=51065 --- reactos/dll/ntdll/include/ntdllp.h | 28 +++ reactos/dll/ntdll/ldr/ldrapi.c | 156 ++++++++++++++++- reactos/dll/ntdll/ldr/ldrinit.c | 265 ++++++++++++++++++++++++++++ reactos/dll/ntdll/ldr/ldrpe.c | 273 +++++++++++++++++++++++++++++ reactos/dll/ntdll/ldr/ldrutils.c | 246 ++++++++++++++++++++++++++ reactos/dll/ntdll/ldr/utils.c | 102 ----------- reactos/dll/ntdll/ntdll.rbuild | 1 + 7 files changed, 967 insertions(+), 104 deletions(-) create mode 100644 reactos/dll/ntdll/ldr/ldrpe.c diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index b7b20ff7f92..dc24500068e 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -23,14 +23,42 @@ typedef BOOL /* Global data */ extern RTL_CRITICAL_SECTION LdrpLoaderLock; +extern BOOLEAN LdrpInLdrInit; /* ldrinit.c */ +NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL); NTSTATUS NTAPI LdrpInitializeTls(VOID); NTSTATUS NTAPI LdrpAllocateTls(VOID); VOID NTAPI LdrpFreeTls(VOID); VOID NTAPI LdrpTlsCallback(PVOID BaseAddress, ULONG Reason); BOOLEAN NTAPI LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint, PVOID BaseAddress, ULONG Reason, PVOID Context); +/* ldrpe.c */ +NTSTATUS +NTAPI +LdrpSnapThunk(IN PVOID ExportBase, + IN PVOID ImportBase, + IN PIMAGE_THUNK_DATA OriginalThunk, + IN OUT PIMAGE_THUNK_DATA Thunk, + IN PIMAGE_EXPORT_DIRECTORY ExportEntry, + IN ULONG ExportSize, + IN BOOLEAN Static, + IN LPSTR DllName); + +/* ldrutils.c */ +NTSTATUS NTAPI +LdrpGetProcedureAddress(IN PVOID BaseAddress, + IN PANSI_STRING Name, + IN ULONG Ordinal, + OUT PVOID *ProcedureAddress, + IN BOOLEAN ExecuteInit); +NTSTATUS NTAPI +LdrpLoadDll(IN BOOLEAN Redirected, + IN PWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PUNICODE_STRING DllName, + OUT PVOID *BaseAddress, + IN BOOLEAN CallInit); /* FIXME: Cleanup this mess */ typedef NTSTATUS (NTAPI *PEPFUNC)(PPEB); diff --git a/reactos/dll/ntdll/ldr/ldrapi.c b/reactos/dll/ntdll/ldr/ldrapi.c index 55e1582a446..af898d035e5 100644 --- a/reactos/dll/ntdll/ldr/ldrapi.c +++ b/reactos/dll/ntdll/ldr/ldrapi.c @@ -109,8 +109,7 @@ LdrLockLoaderLock(IN ULONG Flags, { LONG OldCount; NTSTATUS Status = STATUS_SUCCESS; - BOOLEAN InInit = FALSE; // FIXME - //BOOLEAN InInit = LdrpInLdrInit; + BOOLEAN InInit = LdrpInLdrInit; DPRINT("LdrLockLoaderLock(%x %p %p)\n", Flags, Result, Cookie); @@ -378,4 +377,157 @@ LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle, return !Result ? STATUS_IMAGE_CHECKSUM_MISMATCH : Status; } +/* + * @implemented + */ +NTSTATUS +NTAPI +LdrGetProcedureAddress_(IN PVOID BaseAddress, + IN PANSI_STRING Name, + IN ULONG Ordinal, + OUT PVOID *ProcedureAddress) +{ + /* Call the internal routine and tell it to execute DllInit */ + return LdrpGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress, TRUE); +} + + +NTSTATUS +NTAPI +LdrQueryProcessModuleInformationEx(IN ULONG ProcessId, + IN ULONG Reserved, + IN PRTL_PROCESS_MODULES ModuleInformation, + IN ULONG Size, + OUT PULONG ReturnedSize OPTIONAL) +{ + PLIST_ENTRY ModuleListHead, InitListHead; + PLIST_ENTRY Entry, InitEntry; + PLDR_DATA_TABLE_ENTRY Module, InitModule; + PRTL_PROCESS_MODULE_INFORMATION ModulePtr = NULL; + NTSTATUS Status = STATUS_SUCCESS; + ULONG UsedSize = sizeof(ULONG); + ANSI_STRING AnsiString; + PCHAR p; + + DPRINT("LdrQueryProcessModuleInformation() called\n"); + + /* Acquire loader lock */ + RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); + + /* Check if we were given enough space */ + if (Size < UsedSize) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + ModuleInformation->NumberOfModules = 0; + ModulePtr = &ModuleInformation->Modules[0]; + Status = STATUS_SUCCESS; + } + + /* Traverse the list of modules */ + _SEH2_TRY + { + ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + Entry = ModuleListHead->Flink; + + while (Entry != ModuleListHead) + { + Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + + DPRINT(" Module %wZ\n", &Module->FullDllName); + + /* Increase the used size */ + UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION); + + if (UsedSize > Size) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + ModulePtr->ImageBase = Module->DllBase; + ModulePtr->ImageSize = Module->SizeOfImage; + ModulePtr->Flags = Module->Flags; + ModulePtr->LoadCount = Module->LoadCount; + ModulePtr->MappedBase = NULL; + ModulePtr->InitOrderIndex = 0; + ModulePtr->LoadOrderIndex = ModuleInformation->NumberOfModules; + + /* Now get init order index by traversing init list */ + InitListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList; + InitEntry = InitListHead->Flink; + + while (InitEntry != InitListHead) + { + InitModule = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); + + /* Increase the index */ + ModulePtr->InitOrderIndex++; + + /* Quit the loop if our module is found */ + if (InitModule == Module) break; + + /* Advance to the next entry */ + InitEntry = InitEntry->Flink; + } + + /* Prepare ANSI string with the module's name */ + AnsiString.Length = 0; + AnsiString.MaximumLength = sizeof(ModulePtr->FullPathName); + AnsiString.Buffer = ModulePtr->FullPathName; + RtlUnicodeStringToAnsiString(&AnsiString, + &Module->FullDllName, + FALSE); + + /* Calculate OffsetToFileName field */ + p = strrchr(ModulePtr->FullPathName, '\\'); + if (p != NULL) + ModulePtr->OffsetToFileName = p - ModulePtr->FullPathName + 1; + else + ModulePtr->OffsetToFileName = 0; + + /* Advance to the next module in the output list */ + ModulePtr++; + + /* Increase number of modules */ + if (ModuleInformation) + ModuleInformation->NumberOfModules++; + } + + /* Go to the next entry in the modules list */ + Entry = Entry->Flink; + } + + /* Set returned size if it was provided */ + if (ReturnedSize) + *ReturnedSize = UsedSize; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Ignoring the exception */ + } _SEH2_END; + + /* Release the lock */ + RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); + + DPRINT("LdrQueryProcessModuleInformation() done\n"); + + return Status; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation, + IN ULONG Size, + OUT PULONG ReturnedSize OPTIONAL) +{ + /* Call Ex version of the API */ + return LdrQueryProcessModuleInformationEx(0, 0, ModuleInformation, Size, ReturnedSize); +} + /* EOF */ diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index 72e717beb33..bd15a66cbea 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -20,6 +20,10 @@ HKEY Wow64ExecOptionsKey; UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"); UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); +BOOLEAN LdrpInLdrInit; + +PLDR_DATA_TABLE_ENTRY LdrpImageEntry; + //RTL_BITMAP TlsBitMap; //RTL_BITMAP TlsExpansionBitMap; //RTL_BITMAP FlsBitMap; @@ -329,6 +333,267 @@ LdrQueryImageFileExecutionOptions(IN PUNICODE_STRING SubKey, FALSE); } +NTSTATUS +NTAPI +LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) +{ +#if 0 + PLDR_DATA_TABLE_ENTRY LocalArray[16]; + PLIST_ENTRY ListHead; + PLIST_ENTRY NextEntry; + PLDR_DATA_TABLE_ENTRY LdrEntry, *LdrRootEntry, OldInitializer; + PVOID EntryPoint; + ULONG Count, i; + //ULONG BreakOnInit; + NTSTATUS Status = STATUS_SUCCESS; + PPEB Peb = NtCurrentPeb(); + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx; + ULONG BreakOnDllLoad; + PTEB OldTldTeb; + + DPRINT1("LdrpRunInitializeRoutines() called for %wZ\n", &LdrpImageEntry->BaseDllName); + + /* Check the Loader Lock */ + LdrpEnsureLoaderLockIsHeld(); + + /* Get the number of entries to call */ + if ((Count = LdrpClearLoadInProgress())) + { + /* Check if we can use our local buffer */ + if (Count > 16) + { + /* Allocate space for all the entries */ + LdrRootEntry = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + Count * sizeof(LdrRootEntry)); + if (!LdrRootEntry) return STATUS_NO_MEMORY; + } + else + { + /* Use our local array */ + LdrRootEntry = LocalArray; + } + } + else + { + /* Don't need one */ + LdrRootEntry = NULL; + } + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("[%x,%x] LDR: Real INIT LIST for Process %wZ pid %u %0x%x\n", + NtCurrentTeb()->RealClientId.UniqueThread, + NtCurrentTeb()->RealClientId.UniqueProcess, + Peb->ProcessParameters->ImagePathName, + NtCurrentTeb()->RealClientId.UniqueThread, + NtCurrentTeb()->RealClientId.UniqueProcess); + } + + /* Loop in order */ + ListHead = &Peb->Ldr->InInitializationOrderModuleList; + NextEntry = ListHead->Flink; + i = 0; + while (NextEntry != ListHead) + { + /* Get the Data Entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); + + /* Check if we have a Root Entry */ + if (LdrRootEntry) + { + /* Check flags */ + if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED)) + { + /* Setup the Cookie for the DLL */ + //LdrpInitSecurityCookie(LdrEntry); + UNIMPLEMENTED; + + /* Check for valid entrypoint */ + if (LdrEntry->EntryPoint) + { + /* Write in array */ + LdrRootEntry[i] = LdrEntry; + + /* Display debug message */ + if (ShowSnaps) + { + DPRINT1("[%x,%x] LDR: %wZ init routine %p\n", + NtCurrentTeb()->RealClientId.UniqueThread, + NtCurrentTeb()->RealClientId.UniqueProcess, + &LdrEntry->FullDllName, + LdrEntry->EntryPoint); + } + i++; + } + } + } + + /* Set the flag */ + LdrEntry->Flags |= LDRP_ENTRY_PROCESSED; + NextEntry = NextEntry->Flink; + } + + /* If we got a context, then we have to call Kernel32 for TS support */ + if (Context) + { + /* Check if we have one */ + //if (Kernel32ProcessInitPostImportfunction) + //{ + /* Call it */ + //Kernel32ProcessInitPostImportfunction(); + //} + + /* Clear it */ + //Kernel32ProcessInitPostImportfunction = NULL; + UNIMPLEMENTED; + } + + /* No root entry? return */ + if (!LdrRootEntry) return STATUS_SUCCESS; + + /* Set the TLD TEB */ + OldTldTeb = LdrpTopLevelDllBeingLoadedTeb; + LdrpTopLevelDllBeingLoadedTeb = NtCurrentTeb(); + + /* Loop */ + i = 0; + while (i < Count) + { + /* Get an entry */ + LdrEntry = LdrRootEntry[i]; + + /* FIXME: Verifiy NX Compat */ + + /* Move to next entry */ + i++; + + /* Get its entrypoint */ + EntryPoint = LdrEntry->EntryPoint; + + /* Are we being debugged? */ + BreakOnDllLoad = 0; + if (Peb->BeingDebugged || Peb->ReadImageFileExecOptions) + { + /* Check if we should break on load */ + Status = LdrQueryImageFileExecutionOptions(&LdrEntry->BaseDllName, + L"BreakOnDllLoad", + REG_DWORD, + &BreakOnDllLoad, + sizeof(ULONG), + NULL); + if (!NT_SUCCESS(Status)) BreakOnDllLoad = 0; + } + + /* Break if aksed */ + if (BreakOnDllLoad) + { + /* Check if we should show a message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ loaded.", &LdrEntry->BaseDllName); + DPRINT1(" - About to call init routine at %lx\n", EntryPoint); + } + + /* Break in debugger */ + DbgBreakPoint(); + } + + /* Make sure we have an entrypoint */ + if (EntryPoint) + { + /* Save the old Dll Initializer and write the current one */ + OldInitializer = LdrpCurrentDllInitializer; + LdrpCurrentDllInitializer = LdrEntry; + + /* Set up the Act Ctx */ + ActCtx.Size = sizeof(ActCtx); + ActCtx.Frame.Flags = ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID; + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + + /* Activate the ActCtx */ + RtlActivateActivationContextUnsafeFast(&ActCtx, + LdrEntry->EntryPointActivationContext); + + /* Check if it has TLS */ + if (LdrEntry->TlsIndex && Context) + { + /* Call TLS */ + LdrpTlsCallback(LdrEntry->DllBase, DLL_PROCESS_ATTACH); + } + + /* Call the Entrypoint */ + DPRINT1("%wZ - Calling entry point at %x for thread attaching\n", + &LdrEntry->BaseDllName, EntryPoint); + LdrpCallDllEntry(EntryPoint, + LdrEntry->DllBase, + DLL_PROCESS_ATTACH, + Context); + + /* Deactivate the ActCtx */ + RtlDeactivateActivationContextUnsafeFast(&ActCtx); + + /* Save the Current DLL Initializer */ + LdrpCurrentDllInitializer = OldInitializer; + + /* Mark the entry as processed */ + LdrEntry->Flags |= LDRP_PROCESS_ATTACH_CALLED; + } + } + + /* Loop in order */ + ListHead = &Peb->Ldr->InInitializationOrderModuleList; + NextEntry = NextEntry->Flink; + while (NextEntry != ListHead) + { + /* Get the Data Entrry */ + LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); + + /* FIXME: Verify NX Compat */ + + /* Next entry */ + NextEntry = NextEntry->Flink; + } + + /* Check for TLS */ + if (LdrpImageHasTls && Context) + { + /* Set up the Act Ctx */ + ActCtx.Size = sizeof(ActCtx); + ActCtx.Frame.Flags = ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID; + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + + /* Activate the ActCtx */ + RtlActivateActivationContextUnsafeFast(&ActCtx, + LdrpImageEntry->EntryPointActivationContext); + + /* Do TLS callbacks */ + LdrpTlsCallback(Peb->ImageBaseAddress, DLL_PROCESS_DETACH); + + /* Deactivate the ActCtx */ + RtlDeactivateActivationContextUnsafeFast(&ActCtx); + } + + /* Restore old TEB */ + LdrpTopLevelDllBeingLoadedTeb = OldTldTeb; + + /* Check if the array is in the heap */ + if (LdrRootEntry != LocalArray) + { + /* Free the array */ + RtlFreeHeap(RtlGetProcessHeap(), 0, LdrRootEntry); + } + + /* Return to caller */ + DPRINT("LdrpAttachProcess() done\n"); + return Status; +#else + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +#endif +} + NTSTATUS NTAPI LdrpInitializeTls(VOID) diff --git a/reactos/dll/ntdll/ldr/ldrpe.c b/reactos/dll/ntdll/ldr/ldrpe.c new file mode 100644 index 00000000000..129f756c862 --- /dev/null +++ b/reactos/dll/ntdll/ldr/ldrpe.c @@ -0,0 +1,273 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: lib/ntdll/ldr/ldrpe.c + * PURPOSE: Loader Functions dealing low-level PE Format structures + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ +ULONG LdrpFatalHardErrorCount; +PVOID LdrpManifestProberRoutine; + +/* PROTOTYPES ****************************************************************/ + +#define IMAGE_REL_BASED_HIGH3ADJ 11 + +NTSTATUS +NTAPI +LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, + IN LPSTR ImportName, + IN PVOID DllBase, + OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry, + OUT PBOOLEAN Existing); + +/* FUNCTIONS *****************************************************************/ + +USHORT NTAPI +LdrpNameToOrdinal(LPSTR ImportName, + ULONG NumberOfNames, + PVOID ExportBase, + PULONG NameTable, + PUSHORT OrdinalTable) +{ + UNIMPLEMENTED; + return 0; +} + + +NTSTATUS +NTAPI +LdrpSnapThunk(IN PVOID ExportBase, + IN PVOID ImportBase, + IN PIMAGE_THUNK_DATA OriginalThunk, + IN OUT PIMAGE_THUNK_DATA Thunk, + IN PIMAGE_EXPORT_DIRECTORY ExportEntry, + IN ULONG ExportSize, + IN BOOLEAN Static, + IN LPSTR DllName) +{ + BOOLEAN IsOrdinal; + USHORT Ordinal; + ULONG OriginalOrdinal = 0; + PIMAGE_IMPORT_BY_NAME AddressOfData; + PULONG NameTable; + PUSHORT OrdinalTable; + LPSTR ImportName; + USHORT Hint; + NTSTATUS Status; + ULONG_PTR HardErrorParameters[3]; + UNICODE_STRING HardErrorDllName, HardErrorEntryPointName; + ANSI_STRING TempString; + ULONG Mask; + ULONG Response; + PULONG AddressOfFunctions; + UNICODE_STRING TempUString; + ANSI_STRING ForwarderName; + PANSI_STRING ForwardName; + PVOID ForwarderHandle; + ULONG ForwardOrdinal; + + /* Check if the snap is by ordinal */ + if ((IsOrdinal = IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal))) + { + /* Get the ordinal number, and its normalized version */ + OriginalOrdinal = IMAGE_ORDINAL(OriginalThunk->u1.Ordinal); + Ordinal = (USHORT)(OriginalOrdinal - ExportEntry->Base); + } + else + { + /* First get the data VA */ + AddressOfData = (PIMAGE_IMPORT_BY_NAME) + ((ULONG_PTR)ImportBase + + ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff)); + + /* Get the name */ + ImportName = (LPSTR)AddressOfData->Name; + + /* Now get the VA of the Name and Ordinal Tables */ + NameTable = (PULONG)((ULONG_PTR)ExportBase + + (ULONG_PTR)ExportEntry->AddressOfNames); + OrdinalTable = (PUSHORT)((ULONG_PTR)ExportBase + + (ULONG_PTR)ExportEntry->AddressOfNameOrdinals); + + /* Get the hint */ + Hint = AddressOfData->Hint; + + /* Try to get a match by using the hint */ + if (((ULONG)Hint < ExportEntry->NumberOfNames) && + (!strcmp(ImportName, ((LPSTR)((ULONG_PTR)ExportBase + NameTable[Hint]))))) + { + /* We got a match, get the Ordinal from the hint */ + Ordinal = OrdinalTable[Hint]; + } + else + { + /* Well bummer, hint didn't work, do it the long way */ + Ordinal = LdrpNameToOrdinal(ImportName, + ExportEntry->NumberOfNames, + ExportBase, + NameTable, + OrdinalTable); + } + } + + /* Check if the ordinal is invalid */ + if ((ULONG)Ordinal >= ExportEntry->NumberOfFunctions) + { +FailurePath: + /* Is this a static snap? */ + if (Static) + { + /* These are critical errors. Setup a string for the DLL name */ + RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown"); + RtlAnsiStringToUnicodeString(&HardErrorDllName, &TempString, TRUE); + + /* Set it as the parameter */ + HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllName; + Mask = 2; + + /* Check if we have an ordinal */ + if (IsOrdinal) + { + /* Then set the ordinal as the 1st parameter */ + HardErrorParameters[0] = OriginalOrdinal; + } + else + { + /* We don't, use the entrypoint. Set up a string for it */ + RtlInitAnsiString(&TempString, ImportName); + RtlAnsiStringToUnicodeString(&HardErrorEntryPointName, + &TempString, + TRUE); + + /* Set it as the parameter */ + HardErrorParameters[0] = (ULONG_PTR)&HardErrorEntryPointName; + Mask = 3; + } + + /* Raise the error */ + NtRaiseHardError(IsOrdinal ? STATUS_ORDINAL_NOT_FOUND : + STATUS_ENTRYPOINT_NOT_FOUND, + 2, + Mask, + HardErrorParameters, + OptionOk, + &Response); + + /* Increase the error count */ + if (LdrpInLdrInit) LdrpFatalHardErrorCount++; + + /* Free our string */ + RtlFreeUnicodeString(&HardErrorDllName); + if (!IsOrdinal) + { + /* Free our second string. Return entrypoint error */ + RtlFreeUnicodeString(&HardErrorEntryPointName); + RtlRaiseStatus(STATUS_ENTRYPOINT_NOT_FOUND); + } + + /* Return ordinal error */ + RtlRaiseStatus(STATUS_ORDINAL_NOT_FOUND); + } + + /* Set this as a bad DLL */ + Thunk->u1.Function = (ULONG_PTR)0xffbadd11; + + /* Return the right error code */ + Status = IsOrdinal ? STATUS_ORDINAL_NOT_FOUND : + STATUS_ENTRYPOINT_NOT_FOUND; + } + else + { + /* The ordinal seems correct, get the AddressOfFunctions VA */ + AddressOfFunctions = (PULONG) + ((ULONG_PTR)ExportBase + + (ULONG_PTR)ExportEntry->AddressOfFunctions); + + /* Write the function pointer*/ + Thunk->u1.Function = (ULONG_PTR)ExportBase + AddressOfFunctions[Ordinal]; + + /* Make sure it's within the exports */ + if ((Thunk->u1.Function > (ULONG_PTR)ExportEntry) && + (Thunk->u1.Function < ((ULONG_PTR)ExportEntry + ExportSize))) + { + /* Get the Import and Forwarder Names */ + ImportName = (LPSTR)Thunk->u1.Function; + ForwarderName.Buffer = ImportName; + ForwarderName.Length = (USHORT)(strchr(ImportName, '.') - ImportName); + ForwarderName.MaximumLength = ForwarderName.Length; + Status = RtlAnsiStringToUnicodeString(&TempUString, + &ForwarderName, + TRUE); + + /* Make sure the conversion was OK */ + if (NT_SUCCESS(Status)) + { + /* Load the forwarder, free the temp string */ + Status = LdrpLoadDll(FALSE, + NULL, + NULL, + &TempUString, + &ForwarderHandle, + FALSE); + RtlFreeUnicodeString(&TempUString); + } + + /* If the load or conversion failed, use the failure path */ + if (!NT_SUCCESS(Status)) goto FailurePath; + + /* Now set up a name for the actual forwarder dll */ + RtlInitAnsiString(&ForwarderName, + ImportName + ForwarderName.Length + sizeof(CHAR)); + + /* Check if it's an ordinal forward */ + if ((ForwarderName.Length > 1) && (*ForwarderName.Buffer == '#')) + { + /* We don't have an actual function name */ + ForwardName = NULL; + + /* Convert the string into an ordinal */ + Status = RtlCharToInteger(ForwarderName.Buffer + sizeof(CHAR), + 0, + &ForwardOrdinal); + + /* If this fails, then error out */ + if (!NT_SUCCESS(Status)) goto FailurePath; + } + else + { + /* Import by name */ + ForwardName = &ForwarderName; + } + + /* Get the pointer */ + Status = LdrpGetProcedureAddress(ForwarderHandle, + ForwardName, + ForwardOrdinal, + (PVOID*)&Thunk->u1.Function, + FALSE); + /* If this fails, then error out */ + if (!NT_SUCCESS(Status)) goto FailurePath; + } + else + { + /* It's not within the exports, let's hope it's valid */ + if (!AddressOfFunctions[Ordinal]) goto FailurePath; + } + + /* If we got here, then it's success */ + Status = STATUS_SUCCESS; + } + + /* Return status */ + return Status; +} + +/* EOF */ diff --git a/reactos/dll/ntdll/ldr/ldrutils.c b/reactos/dll/ntdll/ldr/ldrutils.c index 29534cdd992..5c37694807c 100644 --- a/reactos/dll/ntdll/ldr/ldrutils.c +++ b/reactos/dll/ntdll/ldr/ldrutils.c @@ -15,6 +15,8 @@ /* GLOBALS *******************************************************************/ +PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache; + /* FUNCTIONS *****************************************************************/ BOOLEAN @@ -80,4 +82,248 @@ LdrpTlsCallback(PVOID BaseAddress, ULONG Reason) _SEH2_END; } +BOOLEAN +NTAPI +LdrpCheckForLoadedDllHandle(IN PVOID Base, + OUT PLDR_DATA_TABLE_ENTRY *LdrEntry) +{ + PLDR_DATA_TABLE_ENTRY Current; + PLIST_ENTRY ListHead, Next; + + /* Check the cache first */ + if (LdrpLoadedDllHandleCache && LdrpLoadedDllHandleCache->DllBase == Base) + { + /* We got lucky, return the cached entry */ + *LdrEntry = LdrpLoadedDllHandleCache; + return TRUE; + } + + /* Time for a lookup */ + ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + Next = ListHead->Flink; + while(Next != ListHead) + { + /* Get the current entry */ + Current = CONTAINING_RECORD(Next, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* Make sure it's not unloading and check for a match */ + if ((Current->InMemoryOrderModuleList.Flink) && (Base == Current->DllBase)) + { + /* Save in cache */ + LdrpLoadedDllHandleCache = Current; + + /* Return it */ + *LdrEntry = Current; + return TRUE; + } + + /* Move to the next one */ + Next = Next->Flink; + } + + /* Nothing found */ + return FALSE; +} + +BOOLEAN +NTAPI +LdrpCheckForLoadedDll(IN PWSTR DllPath, + IN PUNICODE_STRING DllName, + IN BOOLEAN Flag, + IN BOOLEAN RedirectedDll, + OUT PLDR_DATA_TABLE_ENTRY *LdrEntry) +{ + UNIMPLEMENTED; + return FALSE; +} + +NTSTATUS +NTAPI +LdrpGetProcedureAddress(IN PVOID BaseAddress, + IN PANSI_STRING Name, + IN ULONG Ordinal, + OUT PVOID *ProcedureAddress, + IN BOOLEAN ExecuteInit) +{ + NTSTATUS Status = STATUS_SUCCESS; + UCHAR ImportBuffer[64]; + PLDR_DATA_TABLE_ENTRY LdrEntry; + IMAGE_THUNK_DATA Thunk; + PVOID ImageBase; + PIMAGE_IMPORT_BY_NAME ImportName = NULL; + PIMAGE_EXPORT_DIRECTORY ExportDir; + ULONG ExportDirSize; + PLIST_ENTRY Entry; + + /* Show debug message */ + if (ShowSnaps) DPRINT1("LDR: LdrGetProcedureAddress by "); + + /* Check if we got a name */ + if (Name) + { + /* Show debug message */ + if (ShowSnaps) DPRINT1("NAME - %s\n", Name->Buffer); + + /* Make sure it's not too long */ + if ((Name->Length + sizeof(CHAR) + sizeof(USHORT)) > MAXLONG) + { + /* Won't have enough space to add the hint */ + return STATUS_NAME_TOO_LONG; + } + + /* Check if our buffer is large enough */ + if (Name->Length >= (sizeof(ImportBuffer) - sizeof(CHAR))) + { + /* Allocate from heap, plus 2 bytes for the Hint */ + ImportName = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + Name->Length + sizeof(CHAR) + + sizeof(USHORT)); + } + else + { + /* Use our internal buffer */ + ImportName = (PIMAGE_IMPORT_BY_NAME)ImportBuffer; + } + + /* Clear the hint */ + ImportName->Hint = 0; + + /* Copy the name and null-terminate it */ + RtlMoveMemory(&ImportName->Name, Name->Buffer, Name->Length); + ImportName->Name[Name->Length + 1] = 0; + + /* Clear the high bit */ + ImageBase = ImportName; + Thunk.u1.AddressOfData = 0; + } + else + { + /* Do it by ordinal */ + ImageBase = NULL; + + /* Show debug message */ + if (ShowSnaps) DPRINT1("ORDINAL - %lx\n", Ordinal); + + if (Ordinal) + { + Thunk.u1.Ordinal = Ordinal | IMAGE_ORDINAL_FLAG; + } + else + { + /* No ordinal */ + DPRINT1("No ordinal and no name\n"); + return STATUS_INVALID_PARAMETER; + } + } + + /* Acquire lock unless we are initting */ + if (!LdrpInLdrInit) RtlEnterCriticalSection(&LdrpLoaderLock); + + _SEH2_TRY + { + /* Try to find the loaded DLL */ + if (!LdrpCheckForLoadedDllHandle(BaseAddress, &LdrEntry)) + { + /* Invalid base */ + DPRINT1("Invalid base address\n"); + Status = STATUS_DLL_NOT_FOUND; + _SEH2_YIELD(goto Quickie;) + } + + /* Get the pointer to the export directory */ + ExportDir = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportDirSize); + + if (!ExportDir) + { + DPRINT1("Image has no exports\n"); + Status = STATUS_PROCEDURE_NOT_FOUND; + _SEH2_YIELD(goto Quickie;) + } + + /* Now get the thunk */ + Status = LdrpSnapThunk(LdrEntry->DllBase, + ImageBase, + &Thunk, + &Thunk, + ExportDir, + ExportDirSize, + FALSE, + NULL); + + /* Finally, see if we're supposed to run the init routines */ + if (ExecuteInit) + { + /* + * It's possible a forwarded entry had us load the DLL. In that case, + * then we will call its DllMain. Use the last loaded DLL for this. + */ + Entry = NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Blink; + LdrEntry = CONTAINING_RECORD(Entry, + LDR_DATA_TABLE_ENTRY, + InInitializationOrderModuleList); + + /* Make sure we didn't process it yet*/ + if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED)) + { + /* Call the init routine */ + _SEH2_TRY + { + Status = LdrpRunInitializeRoutines(NULL); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + + /* Make sure we're OK till here */ + if (NT_SUCCESS(Status)) + { + /* Return the address */ + *ProcedureAddress = (PVOID)Thunk.u1.Function; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Just ignore exceptions */ + } + _SEH2_END; + +Quickie: + /* Cleanup */ + if (ImportName && (ImportName != (PIMAGE_IMPORT_BY_NAME)ImportBuffer)) + { + /* We allocated from heap, free it */ + RtlFreeHeap(RtlGetProcessHeap(), 0, ImportName); + } + + /* Release the CS if we entered it */ + if (!LdrpInLdrInit) RtlLeaveCriticalSection(&LdrpLoaderLock); + + /* We're done */ + return Status; +} + +NTSTATUS +NTAPI +LdrpLoadDll(IN BOOLEAN Redirected, + IN PWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PUNICODE_STRING DllName, + OUT PVOID *BaseAddress, + IN BOOLEAN CallInit) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + /* EOF */ diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index e03cb12a3d2..232a6ef7f6b 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -2848,108 +2848,6 @@ LdrShutdownThread (VOID) return STATUS_SUCCESS; } - -/*************************************************************************** - * NAME EXPORTED - * LdrQueryProcessModuleInformation - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - * NOTE - * - * @implemented - */ -NTSTATUS NTAPI -LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIONAL, - IN ULONG Size OPTIONAL, - OUT PULONG ReturnedSize) -{ - PLIST_ENTRY ModuleListHead; - PLIST_ENTRY Entry; - PLDR_DATA_TABLE_ENTRY Module; - PRTL_PROCESS_MODULE_INFORMATION ModulePtr = NULL; - NTSTATUS Status = STATUS_SUCCESS; - ULONG UsedSize = sizeof(ULONG); - ANSI_STRING AnsiString; - PCHAR p; - - DPRINT("LdrQueryProcessModuleInformation() called\n"); -// FIXME: This code is ultra-duplicated. see lib\rtl\dbgbuffer.c - RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); - - if (ModuleInformation == NULL || Size == 0) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - else - { - ModuleInformation->NumberOfModules = 0; - ModulePtr = &ModuleInformation->Modules[0]; - Status = STATUS_SUCCESS; - } - - ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; - Entry = ModuleListHead->Flink; - - while (Entry != ModuleListHead) - { - Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - - DPRINT(" Module %wZ\n", - &Module->FullDllName); - - if (UsedSize > Size) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - else if (ModuleInformation != NULL) - { - ModulePtr->Section = 0; - ModulePtr->MappedBase = NULL; // FIXME: ?? - ModulePtr->ImageBase = Module->DllBase; - ModulePtr->ImageSize = Module->SizeOfImage; - ModulePtr->Flags = Module->Flags; - ModulePtr->LoadOrderIndex = 0; // FIXME: ?? - ModulePtr->InitOrderIndex = 0; // FIXME: ?? - ModulePtr->LoadCount = Module->LoadCount; - - AnsiString.Length = 0; - AnsiString.MaximumLength = 256; - AnsiString.Buffer = ModulePtr->FullPathName; - RtlUnicodeStringToAnsiString(&AnsiString, - &Module->FullDllName, - FALSE); - - p = strrchr(ModulePtr->FullPathName, '\\'); - if (p != NULL) - ModulePtr->OffsetToFileName = p - ModulePtr->FullPathName + 1; - else - ModulePtr->OffsetToFileName = 0; - - ModulePtr++; - ModuleInformation->NumberOfModules++; - } - UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION); - - Entry = Entry->Flink; - } - - RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); - - if (ReturnedSize != 0) - *ReturnedSize = UsedSize; - - DPRINT("LdrQueryProcessModuleInformation() done\n"); - - return(Status); -} - /* * Compute size of an image as it is actually present in virt memory * (i.e. excluding NEVER_LOAD sections) diff --git a/reactos/dll/ntdll/ntdll.rbuild b/reactos/dll/ntdll/ntdll.rbuild index 544a53b67ea..384a6c96ff6 100644 --- a/reactos/dll/ntdll/ntdll.rbuild +++ b/reactos/dll/ntdll/ntdll.rbuild @@ -49,6 +49,7 @@ ldrapi.c ldrinit.c + ldrpe.c ldrutils.c startup.c utils.c From 0416030d2ae618247e9440f85ca3c149c29a2943 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 16 Mar 2011 15:18:52 +0000 Subject: [PATCH 15/90] [WDMAUD_KERNEL] - Don't alter the IoStatus.Information field with the number of bytes written - Fixes sndrec32 crash (now also working in ReactOS) - Should be merged to 0.3.13 ;) svn path=/trunk/; revision=51067 --- .../drivers/wdm/audio/legacy/wdmaud/control.c | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index afc692c15ac..3343405de41 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -402,28 +402,6 @@ IoCompletion ( /* sanity check */ ASSERT(Header); - /* iterate through all stream headers and collect size */ - do - { - if (Context->Function == IOCTL_KS_READ_STREAM) - { - /* length is stored in DataUsed */ - Length += Header->DataUsed; - } - else - { - /* length stored in frameextend */ - Length += Header->FrameExtent; - } - - /* subtract size */ - Context->Length -= Header->Size; - - /* move to next stream header */ - Header = (PKSSTREAM_HEADER)((ULONG_PTR)Header + Header->Size); - - }while(Context->Length); - /* time to free all allocated mdls */ Mdl = Irp->MdlAddress; @@ -454,12 +432,7 @@ IoCompletion ( DPRINT("IoCompletion Irp %p IoStatus %lx Information %lx Length %lu\n", Irp, Irp->IoStatus.Status, Irp->IoStatus.Information, Length); - if (Irp->IoStatus.Status == STATUS_SUCCESS) - { - /* store the length */ - Irp->IoStatus.Information = Length; - } - else + if (!NT_SUCCESS(Irp->IoStatus.Status)) { /* failed */ Irp->IoStatus.Information = 0; @@ -471,7 +444,6 @@ IoCompletion ( return STATUS_SUCCESS; } - NTSTATUS NTAPI WdmAudReadWrite( From 58230f89ccc41ac9496193aec241e51ee703d393 Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Wed, 16 Mar 2011 16:46:37 +0000 Subject: [PATCH 16/90] [SHELL32] Thomas Faber - Fix memory leak in RenderHDROP. Modifications by me to have just a single return statement in the function. See issue #5998 for more details. svn path=/trunk/; revision=51069 --- reactos/dll/win32/shell32/clipboard.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/reactos/dll/win32/shell32/clipboard.c b/reactos/dll/win32/shell32/clipboard.c index 0c989c6ddd5..24fd0d0f514 100644 --- a/reactos/dll/win32/shell32/clipboard.c +++ b/reactos/dll/win32/shell32/clipboard.c @@ -49,15 +49,16 @@ HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) UINT i; int size = 0; WCHAR wszFileName[MAX_PATH]; - HGLOBAL hGlobal; + HGLOBAL hGlobal = NULL; DROPFILES *pDropFiles; int offset; LPITEMIDLIST *pidls; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); - pidls = HeapAlloc(GetProcessHeap(), 0, cidl * sizeof *pidls); - if (!pidls) return NULL; + pidls = HeapAlloc(GetProcessHeap(), 0, cidl * sizeof(*pidls)); + if (!pidls) + goto cleanup; /* get the size needed */ size = sizeof(DROPFILES); @@ -73,7 +74,8 @@ HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) /* Fill the structure */ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); - if(!hGlobal) return hGlobal; + if(!hGlobal) + goto cleanup; pDropFiles = (DROPFILES *)GlobalLock(hGlobal); offset = (sizeof(DROPFILES) + sizeof(WCHAR) - 1) / sizeof(WCHAR); @@ -91,7 +93,9 @@ HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) ((WCHAR*)pDropFiles)[offset] = 0; GlobalUnlock(hGlobal); - HeapFree(GetProcessHeap(), 0, pidls); +cleanup: + if(pidls) + HeapFree(GetProcessHeap(), 0, pidls); return hGlobal; } From 64c7077d57d0243ca168a5de2d3151c279afc7a2 Mon Sep 17 00:00:00 2001 From: Roel Messiant Date: Wed, 16 Mar 2011 21:07:25 +0000 Subject: [PATCH 17/90] [GENERAL] Patch by Rafal Harabien (rafalh1992 at o2 dot pl) - Change () to (VOID) in function declarators. Part 6/XX. [USETUP] Patch by Rafal Harabien (rafalh1992 at o2 dot pl) - Initialize Offset field of partition list. Spotted using DPH. svn path=/trunk/; revision=51072 --- reactos/base/applications/paint/dialogs.h | 2 +- reactos/base/setup/usetup/partlist.c | 1 + reactos/base/shell/explorer/externals.h | 2 +- .../shell/explorer/notifyhook/notifyhook.h | 4 +- .../freeldr/freeldr/arch/powerpc/compat.h | 2 +- .../boot/freeldr/freeldr/arch/powerpc/prep.h | 4 +- .../freeldr/include/arch/amd64/amd64.h | 2 +- .../freeldr/include/arch/amd64/machpc.h | 4 +- .../boot/freeldr/freeldr/include/machine.h | 4 +- .../storage/ide/uniata/inc/PostDbgMesg.h | 4 +- reactos/drivers/usb/nt4compat/usbdriver/usb.h | 2 +- reactos/drivers/usb/usbehci/physmem.h | 2 +- .../video/displays/vga/vgavideo/vgavideo.h | 2 +- reactos/drivers/video/miniport/vga/vgamp.h | 4 +- .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 10 ++-- reactos/include/crt/eh.h | 10 ++-- reactos/include/crt/rtcapi.h | 4 +- reactos/include/crt/xlocinfo.h | 14 +++--- reactos/include/psdk/commctrl.h | 2 +- reactos/include/psdk/ntgdi.h | 8 +-- reactos/include/psdk/shlwapi_undoc.h | 6 +-- reactos/include/psdk/uxtheme.h | 6 +-- reactos/include/psdk/ws2tcpip.h | 2 +- .../include/reactos/drivers/directx/dxeng.h | 16 +++--- .../include/reactos/libs/audiosrv/audiosrv.h | 8 +-- reactos/include/reactos/libs/ppcmmu/mmuutil.h | 6 +-- reactos/include/reactos/libs/sound/mmebuddy.h | 8 +-- reactos/include/reactos/libs/sound/time.h | 2 +- .../lib/drivers/oskittcp/include/oskittcp.h | 4 +- reactos/lib/fslib/vfatlib/check/io.h | 4 +- reactos/lib/ppcmmu/mmuobject.h | 4 +- reactos/ntoskrnl/include/internal/amd64/ke.h | 50 +++++++++---------- reactos/ntoskrnl/include/internal/kd.h | 2 +- reactos/ntoskrnl/kdbg/kdb.h | 8 +-- .../win32/win32k/include/callback.h | 2 +- .../win32/win32k/include/cursoricon.h | 6 +-- reactos/subsystems/win32/win32k/include/dc.h | 4 +- .../subsystems/win32/win32k/include/device.h | 2 +- .../win32/win32k/include/gdidebug.h | 4 +- .../subsystems/win32/win32k/include/gdiobj.h | 2 +- .../subsystems/win32/win32k/include/input.h | 2 +- .../subsystems/win32/win32k/include/ldevobj.h | 2 +- .../subsystems/win32/win32k/include/monitor.h | 4 +- .../win32/win32k/include/msgqueue.h | 4 +- .../subsystems/win32/win32k/include/palette.h | 2 +- .../subsystems/win32/win32k/include/pdevobj.h | 2 +- 46 files changed, 125 insertions(+), 124 deletions(-) diff --git a/reactos/base/applications/paint/dialogs.h b/reactos/base/applications/paint/dialogs.h index 4378045ecc5..377a3198d5e 100644 --- a/reactos/base/applications/paint/dialogs.h +++ b/reactos/base/applications/paint/dialogs.h @@ -10,4 +10,4 @@ int mirrorRotateDlg(void); int attributesDlg(void); -int changeSizeDlg(); +int changeSizeDlg(void); diff --git a/reactos/base/setup/usetup/partlist.c b/reactos/base/setup/usetup/partlist.c index 7e2c7510976..52a0259d99e 100644 --- a/reactos/base/setup/usetup/partlist.c +++ b/reactos/base/setup/usetup/partlist.c @@ -944,6 +944,7 @@ CreatePartitionList (SHORT Left, List->Bottom = Bottom; List->Line = 0; + List->Offset = 0; List->TopDisk = (ULONG)-1; List->TopPartition = (ULONG)-1; diff --git a/reactos/base/shell/explorer/externals.h b/reactos/base/shell/explorer/externals.h index 0d3eb518ef6..5e9d5fa0794 100644 --- a/reactos/base/shell/explorer/externals.h +++ b/reactos/base/shell/explorer/externals.h @@ -41,7 +41,7 @@ extern void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine=NULL); extern void explorer_about(HWND hwndParent); // test for already running desktop instance -extern BOOL IsAnyDesktopRunning(); +extern BOOL IsAnyDesktopRunning(void); // show shutdown dialog extern void ShowExitWindowsDialog(HWND hwndOwner); diff --git a/reactos/base/shell/explorer/notifyhook/notifyhook.h b/reactos/base/shell/explorer/notifyhook/notifyhook.h index 0982d71113e..bfa4b356156 100644 --- a/reactos/base/shell/explorer/notifyhook/notifyhook.h +++ b/reactos/base/shell/explorer/notifyhook/notifyhook.h @@ -39,8 +39,8 @@ extern "C" { #endif -DECL_NOTIFYHOOK UINT InstallNotifyHook(); -DECL_NOTIFYHOOK void DeinstallNotifyHook(); +DECL_NOTIFYHOOK UINT InstallNotifyHook(void); +DECL_NOTIFYHOOK void DeinstallNotifyHook(void); DECL_NOTIFYHOOK void GetWindowModulePath(HWND hwnd); DECL_NOTIFYHOOK int GetWindowModulePathCopyData(LPARAM lparam, HWND* phwnd, LPSTR buffer, int size); diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h index 3bc1b7998d7..b81894233ec 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h @@ -102,4 +102,4 @@ void btext_drawhex(unsigned long v); void *ioremap(__u32 phys, __u32 size); void iounmap(void *logical); -__u32 GetPVR(); +__u32 GetPVR(void); diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h b/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h index ea03fa0ae1f..4761d8f9c15 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h @@ -7,8 +7,8 @@ struct _pci_bar { unsigned long data; }; -void sync(); -void PpcPrepInit(); +void sync( void ); +void PpcPrepInit( void ); void ide_seek( void *extension, int low, int high ); int ide_read( void *extension, char *buffer, int bytes ); void ide_setup( void *extension ); diff --git a/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h b/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h index 9068e00f90a..e5c73d4b4e5 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h +++ b/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h @@ -58,7 +58,7 @@ typedef struct _PAGE_DIRECTORY_AMD64 } PAGE_DIRECTORY_AMD64, *PPAGE_DIRECTORY_AMD64; -VOID FrLdrSetupGdtIdt(); +VOID FrLdrSetupGdtIdt(VOID); #endif diff --git a/reactos/boot/freeldr/freeldr/include/arch/amd64/machpc.h b/reactos/boot/freeldr/freeldr/include/arch/amd64/machpc.h index 2efd7e8c74a..efcf293dcab 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/amd64/machpc.h +++ b/reactos/boot/freeldr/freeldr/include/arch/amd64/machpc.h @@ -29,8 +29,8 @@ VOID PcMachInit(const char *CmdLine); VOID PcConsPutChar(int Ch); -BOOLEAN PcConsKbHit(); -int PcConsGetCh(); +BOOLEAN PcConsKbHit(VOID); +int PcConsGetCh(VOID); VOID PcVideoClearScreen(UCHAR Attr); VIDEODISPLAYMODE PcVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init); diff --git a/reactos/boot/freeldr/freeldr/include/machine.h b/reactos/boot/freeldr/freeldr/include/machine.h index 65952056faa..ba2be4fdf6a 100644 --- a/reactos/boot/freeldr/freeldr/include/machine.h +++ b/reactos/boot/freeldr/freeldr/include/machine.h @@ -77,8 +77,8 @@ VOID MachInit(const char *CmdLine); extern MACHVTBL MachVtbl; VOID MachConsPutChar(int Ch); -BOOLEAN MachConsKbHit(); -int MachConsGetCh(); +BOOLEAN MachConsKbHit(VOID); +int MachConsGetCh(VOID); VOID MachVideoClearScreen(UCHAR Attr); VIDEODISPLAYMODE MachVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init); VOID MachVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth); diff --git a/reactos/drivers/storage/ide/uniata/inc/PostDbgMesg.h b/reactos/drivers/storage/ide/uniata/inc/PostDbgMesg.h index 964de7ea3f9..5c30d729c0e 100644 --- a/reactos/drivers/storage/ide/uniata/inc/PostDbgMesg.h +++ b/reactos/drivers/storage/ide/uniata/inc/PostDbgMesg.h @@ -27,11 +27,11 @@ DbgDump_Printn( BOOLEAN __stdcall -DbgDump_Reconnect(); +DbgDump_Reconnect(VOID); VOID __stdcall -DbgDump_Disconnect(); +DbgDump_Disconnect(VOID); VOID __stdcall diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usb.h b/reactos/drivers/usb/nt4compat/usbdriver/usb.h index 9130c3ede79..29a8ce91d50 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usb.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/usb.h @@ -1049,7 +1049,7 @@ PLARGE_INTEGER clicks ); VOID -usb_cal_cpu_freq(); +usb_cal_cpu_freq(VOID); NTSTATUS usb_reset_pipe_ex( diff --git a/reactos/drivers/usb/usbehci/physmem.h b/reactos/drivers/usb/usbehci/physmem.h index ef1355da9df..a49f1bbda6d 100644 --- a/reactos/drivers/usb/usbehci/physmem.h +++ b/reactos/drivers/usb/usbehci/physmem.h @@ -16,7 +16,7 @@ typedef struct _MEM_HEADER } MEM_HEADER, *PMEM_HEADER; VOID -DumpPages(); +DumpPages(VOID); ULONG AllocateMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Size, ULONG *PhysicalAddress); diff --git a/reactos/drivers/video/displays/vga/vgavideo/vgavideo.h b/reactos/drivers/video/displays/vga/vgavideo/vgavideo.h index dbd7259df6d..69015a5a3ad 100644 --- a/reactos/drivers/video/displays/vga/vgavideo/vgavideo.h +++ b/reactos/drivers/video/displays/vga/vgavideo/vgavideo.h @@ -41,7 +41,7 @@ typedef struct _VideoMode { unsigned char Attrib[21]; } VideoMode; -VOID vgaPreCalc(); +VOID vgaPreCalc(VOID); VOID vgaPutPixel(INT x, INT y, UCHAR c); VOID vgaPutByte(INT x, INT y, UCHAR c); VOID vgaGetByte(ULONG offset, diff --git a/reactos/drivers/video/miniport/vga/vgamp.h b/reactos/drivers/video/miniport/vga/vgamp.h index 2e018e4b116..acece1cfe24 100644 --- a/reactos/drivers/video/miniport/vga/vgamp.h +++ b/reactos/drivers/video/miniport/vga/vgamp.h @@ -34,8 +34,8 @@ #define UNIMPLEMENTED \ VideoPortDebugPrint(Error, "WARNING: %s at %s:%d is UNIMPLEMENTED!\n",__FUNCTION__,__FILE__,__LINE__); -void -InitVGAMode(); +VOID +InitVGAMode(VOID); VP_STATUS NTAPI VGAFindAdapter( diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 002cf8d0d0a..c322c3fc8a9 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -280,19 +280,19 @@ OpenDevice( OUT PFILE_OBJECT * FileObject); ULONG -WdmAudGetMixerDeviceCount(); +WdmAudGetMixerDeviceCount(VOID); ULONG -WdmAudGetWaveInDeviceCount(); +WdmAudGetWaveInDeviceCount(VOID); ULONG -WdmAudGetWaveOutDeviceCount(); +WdmAudGetWaveOutDeviceCount(VOID); ULONG -WdmAudGetMidiInDeviceCount(); +WdmAudGetMidiInDeviceCount(VOID); ULONG -WdmAudGetMidiOutDeviceCount(); +WdmAudGetMidiOutDeviceCount(VOID); NTSTATUS WdmAudGetPnpNameByIndexAndType( diff --git a/reactos/include/crt/eh.h b/reactos/include/crt/eh.h index 3c7725a42c2..8d2264b1db1 100644 --- a/reactos/include/crt/eh.h +++ b/reactos/include/crt/eh.h @@ -16,10 +16,10 @@ #error eh.h is only for C++! #endif -typedef void (__cdecl *terminate_function)(); -typedef void (__cdecl *terminate_handler)(); -typedef void (__cdecl *unexpected_function)(); -typedef void (__cdecl *unexpected_handler)(); +typedef void (__cdecl *terminate_function)(void); +typedef void (__cdecl *terminate_handler)(void); +typedef void (__cdecl *unexpected_function)(void); +typedef void (__cdecl *unexpected_handler)(void); struct _EXCEPTION_POINTERS; typedef void (__cdecl *_se_translator_function)(unsigned int,struct _EXCEPTION_POINTERS *); @@ -32,7 +32,7 @@ extern "C" _CRTIMP terminate_function __cdecl _get_terminate(void); _CRTIMP unexpected_function __cdecl set_unexpected(unexpected_function _NewPtFunc); extern "C" _CRTIMP unexpected_function __cdecl _get_unexpected(void); _CRTIMP _se_translator_function __cdecl _set_se_translator(_se_translator_function _NewPtFunc); -_CRTIMP bool __cdecl __uncaught_exception(); +_CRTIMP bool __cdecl __uncaught_exception(void); #pragma pack(pop) #endif diff --git a/reactos/include/crt/rtcapi.h b/reactos/include/crt/rtcapi.h index 3816f2d25c8..44b7f873af9 100644 --- a/reactos/include/crt/rtcapi.h +++ b/reactos/include/crt/rtcapi.h @@ -76,7 +76,7 @@ extern "C" { __MINGW_EXTENSION int __fastcall _RTC_Check_8_to_4(__int64 _Src); #if (defined(_X86_) && !defined(__x86_64)) - void __cdecl _RTC_CheckEsp(); + void __cdecl _RTC_CheckEsp(void); #endif void __fastcall _RTC_CheckStackVars(void *_Esp,_RTC_framedesc *_Fd); void __fastcall _RTC_CheckStackVars2(void *_Esp,_RTC_framedesc *_Fd,_RTC_ALLOCA_NODE *_AllocaList); @@ -85,7 +85,7 @@ extern "C" { void __cdecl _RTC_Shutdown(void); void __cdecl _RTC_InitBase(void); #ifdef __cplusplus - void *_ReturnAddress(); + void *_ReturnAddress(void); } #endif diff --git a/reactos/include/crt/xlocinfo.h b/reactos/include/crt/xlocinfo.h index 514ae672e57..efa67fb85b4 100644 --- a/reactos/include/crt/xlocinfo.h +++ b/reactos/include/crt/xlocinfo.h @@ -62,10 +62,10 @@ typedef struct _Cvtvec { unsigned int _Page; } _Cvtvec; -_CRTIMP _Collvec __cdecl _Getcoll(); -_CRTIMP _Ctypevec __cdecl _Getctype(); -_CRTIMP _Cvtvec __cdecl _Getcvt(); -_CRTIMP int __cdecl _Getdateorder(); +_CRTIMP _Collvec __cdecl _Getcoll(void); +_CRTIMP _Ctypevec __cdecl _Getctype(void); +_CRTIMP _Cvtvec __cdecl _Getcvt(void); +_CRTIMP int __cdecl _Getdateorder(void); _CRTIMP int __cdecl _Mbrtowc(wchar_t *,const char *,size_t,mbstate_t *,const _Cvtvec *); _CRTIMP float __cdecl _Stof(const char *,char **,long); _CRTIMP double __cdecl _Stod(const char *,char **,long); @@ -85,9 +85,9 @@ _END_C_LIB_DECL _C_STD_END _C_LIB_DECL -_CRTIMP void *__cdecl _Gettnames(); -_CRTIMP char *__cdecl _Getdays(); -_CRTIMP char *__cdecl _Getmonths(); +_CRTIMP void *__cdecl _Gettnames(void); +_CRTIMP char *__cdecl _Getdays(void); +_CRTIMP char *__cdecl _Getmonths(void); _CRTIMP size_t __cdecl _Strftime(char *,size_t _Maxsize,const char *,const struct tm *,void *); _END_C_LIB_DECL diff --git a/reactos/include/psdk/commctrl.h b/reactos/include/psdk/commctrl.h index 2b2bfd38bd7..a6563982eaa 100644 --- a/reactos/include/psdk/commctrl.h +++ b/reactos/include/psdk/commctrl.h @@ -381,7 +381,7 @@ extern "C" { #define ILCF_SWAP 0x1 WINCOMMCTRLAPI WINBOOL WINAPI ImageList_Copy(HIMAGELIST himlDst,int iDst,HIMAGELIST himlSrc,int iSrc,UINT uFlags); WINCOMMCTRLAPI WINBOOL WINAPI ImageList_BeginDrag(HIMAGELIST himlTrack,int iTrack,int dxHotspot,int dyHotspot); - WINCOMMCTRLAPI void WINAPI ImageList_EndDrag(); + WINCOMMCTRLAPI void WINAPI ImageList_EndDrag(void); WINCOMMCTRLAPI WINBOOL WINAPI ImageList_DragEnter(HWND hwndLock,int x,int y); WINCOMMCTRLAPI WINBOOL WINAPI ImageList_DragLeave(HWND hwndLock); WINCOMMCTRLAPI WINBOOL WINAPI ImageList_DragMove(int x,int y); diff --git a/reactos/include/psdk/ntgdi.h b/reactos/include/psdk/ntgdi.h index e8050217a23..0ce2e6df05b 100644 --- a/reactos/include/psdk/ntgdi.h +++ b/reactos/include/psdk/ntgdi.h @@ -80,7 +80,7 @@ typedef struct tagDOWNLOADDESIGNVECTOR W32KAPI BOOL APIENTRY -NtGdiInit(); +NtGdiInit(VOID); W32KAPI INT @@ -1239,7 +1239,7 @@ NtGdiIcmBrushInfo( W32KAPI VOID APIENTRY -NtGdiFlush(); +NtGdiFlush(VOID); W32KAPI HDC @@ -3277,7 +3277,7 @@ NtGdiCLIPOBJ_ppoGetPath( W32KAPI CLIPOBJ* APIENTRY -NtGdiEngCreateClip(); +NtGdiEngCreateClip(VOID); W32KAPI VOID @@ -3660,7 +3660,7 @@ NtGdiMakeObjectUnXferable( W32KAPI BOOL APIENTRY -NtGdiInitSpool(); +NtGdiInitSpool(VOID); /* FIXME wrong prototypes fix the build */ W32KAPI diff --git a/reactos/include/psdk/shlwapi_undoc.h b/reactos/include/psdk/shlwapi_undoc.h index 11cb464cdc7..41f60a13e9e 100644 --- a/reactos/include/psdk/shlwapi_undoc.h +++ b/reactos/include/psdk/shlwapi_undoc.h @@ -47,7 +47,7 @@ struct IEThreadParamBlock void WINAPI InitOCHostClass(long param8); long WINAPI SHOpenFolderWindow(IEThreadParamBlock *param8); -void WINAPI SHCreateSavedWindows(); +void WINAPI SHCreateSavedWindows(void); long WINAPI SHCreateFromDesktop(long param8); long WINAPI SHExplorerParseCmdLine(LPCTSTR commandLine); void WINAPI UEMRegisterNotify(long param8, long paramC); @@ -59,11 +59,11 @@ IEThreadParamBlock *WINAPI SHCloneIETHREADPARAM(IEThreadParamBlock *param); long WINAPI SHParseIECommandLine(long param8, long paramC); void WINAPI SHDestroyIETHREADPARAM(IEThreadParamBlock *param); HRESULT WINAPI SHOnCWMCommandLine(long param8); -LPITEMIDLIST WINAPI Channel_GetFolderPidl(); +LPITEMIDLIST WINAPI Channel_GetFolderPidl(void); IUnknown *WINAPI ChannelBand_Create(LPITEMIDLIST pidl); HRESULT WINAPI Channels_SetBandInfoSFB(IUnknown *param8); HRESULT WINAPI IUnknown_SetBandInfoSFB(IUnknown *param8, long paramC); -HRESULT WINAPI Channel_QuickLaunch(); +HRESULT WINAPI Channel_QuickLaunch(void); HRESULT WINAPI SHGetNavigateTarget(long param8, long paramC, long param10, long param14); HRESULT WINAPI GetInfoTip(IUnknown *param8, long paramC, LPTSTR *param10, long cchMax); HRESULT WINAPI SHEnumClassesOfCategories(long param8, long paramC, long param10, long param14, long param18); diff --git a/reactos/include/psdk/uxtheme.h b/reactos/include/psdk/uxtheme.h index 5cda082bd8c..ad2b3694d7e 100644 --- a/reactos/include/psdk/uxtheme.h +++ b/reactos/include/psdk/uxtheme.h @@ -96,7 +96,7 @@ HRESULT WINAPI DrawThemeText(HTHEME,HDC,int,int,LPCWSTR,int,DWORD,DWORD,const RE HRESULT WINAPI EnableThemeDialogTexture(HWND,DWORD); HRESULT WINAPI EnableTheming(BOOL); HRESULT WINAPI GetCurrentThemeName(LPWSTR,int,LPWSTR,int,LPWSTR,int); -DWORD WINAPI GetThemeAppProperties(); +DWORD WINAPI GetThemeAppProperties(void); HRESULT WINAPI GetThemeBackgroundContentRect(HTHEME,HDC,int,int,const RECT*,RECT*); HRESULT WINAPI GetThemeBackgroundExtent(HTHEME,HDC,int,int,const RECT*,RECT*); HRESULT WINAPI GetThemeBackgroundRegion(HTHEME,HDC,int,int,const RECT*,HRGN*); @@ -126,8 +126,8 @@ HRESULT WINAPI GetThemeTextExtent(HTHEME,HDC,int,int,LPCWSTR,int,DWORD,const REC HRESULT WINAPI GetThemeTextMetrics(HTHEME,HDC,int,int,TEXTMETRICW*); HTHEME WINAPI GetWindowTheme(HWND); HRESULT WINAPI HitTestThemeBackground(HTHEME,HDC,int,int,DWORD,const RECT*,HRGN,POINT,WORD*); -BOOL WINAPI IsAppThemed(); -BOOL WINAPI IsThemeActive(); +BOOL WINAPI IsAppThemed(void); +BOOL WINAPI IsThemeActive(void); BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME,int,int); BOOL WINAPI IsThemeDialogTextureEnabled(HWND); BOOL WINAPI IsThemePartDefined(HTHEME,int,int); diff --git a/reactos/include/psdk/ws2tcpip.h b/reactos/include/psdk/ws2tcpip.h index d6e8620b632..a3487f33007 100644 --- a/reactos/include/psdk/ws2tcpip.h +++ b/reactos/include/psdk/ws2tcpip.h @@ -835,7 +835,7 @@ WSAImpersonateSocketPeer( WINSOCK_API_LINKAGE INT WSAAPI -WSARevertImpersonation(); +WSARevertImpersonation(VOID); #endif /* _SECURE_SOCKET_TYPES_DEFINED_ */ #endif /* (_WIN32_WINNT >= 0x0600) */ diff --git a/reactos/include/reactos/drivers/directx/dxeng.h b/reactos/include/reactos/drivers/directx/dxeng.h index dcd5520c553..c4ddf18c0c5 100644 --- a/reactos/include/reactos/drivers/directx/dxeng.h +++ b/reactos/include/reactos/drivers/directx/dxeng.h @@ -73,7 +73,7 @@ typedef enum _DXEGSHDEVDATA /************************************************************************/ /* win32k.sys internal protypes for driver functions it exports */ /************************************************************************/ -BOOLEAN NTAPI DxEngNUIsTermSrv(); +BOOLEAN NTAPI DxEngNUIsTermSrv(VOID); PDC NTAPI DxEngLockDC(HDC hDC); BOOLEAN NTAPI DxEngUnlockDC(PDC pDC); DWORD_PTR NTAPI DxEngGetHdevData(HDEV, DXEGSHDEVDATA); @@ -82,20 +82,20 @@ BOOLEAN NTAPI DxEngLockHdev(HDEV hdev); BOOLEAN NTAPI DxEngUnlockHdev(HDEV hdev); DWORD_PTR NTAPI DxEngGetDCState(HDC hDC, DWORD type); BOOLEAN NTAPI DxEngReferenceHdev(HDEV hdev); -BOOLEAN NTAPI DxEngLockShareSem(); -BOOLEAN NTAPI DxEngUnlockShareSem(); -DWORD NTAPI DxEngScreenAccessCheck(); +BOOLEAN NTAPI DxEngLockShareSem(VOID); +BOOLEAN NTAPI DxEngUnlockShareSem(VOID); +DWORD NTAPI DxEngScreenAccessCheck(VOID); BOOL NTAPI DxEngSetDCOwner(HGDIOBJ hObject, DWORD OwnerMask); /* Prototypes for the following functions are not yet finished */ -BOOLEAN NTAPI DxEngRedrawDesktop(); -ULONG NTAPI DxEngDispUniq(); -ULONG NTAPI DxEngVisRgnUniq(); +BOOLEAN NTAPI DxEngRedrawDesktop(VOID); +ULONG NTAPI DxEngDispUniq(VOID); +ULONG NTAPI DxEngVisRgnUniq(VOID); HDEV* NTAPI DxEngEnumerateHdev(HDEV *hdev); BOOL NTAPI DxEngGetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp); BOOLEAN NTAPI DxEngSetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp, BOOL Unuse); BOOLEAN NTAPI DxEngCleanDC(HDC hdc); -BOOLEAN NTAPI DxEngIncDispUniq(); +BOOLEAN NTAPI DxEngIncDispUniq(VOID); HDC NTAPI DxEngCreateMemoryDC(HDEV hDev); diff --git a/reactos/include/reactos/libs/audiosrv/audiosrv.h b/reactos/include/reactos/libs/audiosrv/audiosrv.h index 0edc7d0abc2..ccaab5b0f23 100644 --- a/reactos/include/reactos/libs/audiosrv/audiosrv.h +++ b/reactos/include/reactos/libs/audiosrv/audiosrv.h @@ -46,15 +46,15 @@ typedef struct ( (lstrlenW(str) + 1) * sizeof(WCHAR) ) BOOL -InitializeAudioDeviceListLock(); +InitializeAudioDeviceListLock(VOID); VOID -KillAudioDeviceListLock(); +KillAudioDeviceListLock(VOID); VOID -LockAudioDeviceList(); +LockAudioDeviceList(VOID); VOID -UnlockAudioDeviceList(); +UnlockAudioDeviceList(VOID); #endif diff --git a/reactos/include/reactos/libs/ppcmmu/mmuutil.h b/reactos/include/reactos/libs/ppcmmu/mmuutil.h index 9528b571fc4..955028b33d6 100644 --- a/reactos/include/reactos/libs/ppcmmu/mmuutil.h +++ b/reactos/include/reactos/libs/ppcmmu/mmuutil.h @@ -1,8 +1,8 @@ #ifndef FREELDR_MMU_H #define FREELDR_MMU_H -int GetDEC(); -int GetMSR(); +int GetDEC(void); +int GetMSR(void); int GetPhys( paddr_t addr ); int GetPhysHalf( paddr_t addr ); int GetPhysByte( paddr_t addr ); @@ -13,7 +13,7 @@ int GetSR(int n); void SetSR(int n, int val); void GetBat( int bat, int inst, int *batHi, int *batLo ); void SetBat( int bat, int inst, int batHi, int batLo ); -int GetSDR1(); +int GetSDR1(void); void SetSDR1( int newsdr ); int BatHit( int bath, int batl, int virt ); int BatTranslate( int bath, int batl, int virt ); diff --git a/reactos/include/reactos/libs/sound/mmebuddy.h b/reactos/include/reactos/libs/sound/mmebuddy.h index d1139c7d867..aadbb3ae617 100644 --- a/reactos/include/reactos/libs/sound/mmebuddy.h +++ b/reactos/include/reactos/libs/sound/mmebuddy.h @@ -382,10 +382,10 @@ typedef struct _WAVEHDR_EXTENSION */ MMRESULT -InitEntrypointMutexes(); +InitEntrypointMutexes(VOID); VOID -CleanupEntrypointMutexes(); +CleanupEntrypointMutexes(VOID); VOID AcquireEntrypointMutex( @@ -502,7 +502,7 @@ UnlistSoundDevices( IN MMDEVICE_TYPE DeviceType); VOID -UnlistAllSoundDevices(); +UnlistAllSoundDevices(VOID); MMRESULT GetSoundDevice( @@ -608,7 +608,7 @@ FreeMemory( IN PVOID Pointer); UINT -GetMemoryAllocationCount(); +GetMemoryAllocationCount(VOID); UINT GetDigitCount( diff --git a/reactos/include/reactos/libs/sound/time.h b/reactos/include/reactos/libs/sound/time.h index 56378e8680c..7308253d84f 100644 --- a/reactos/include/reactos/libs/sound/time.h +++ b/reactos/include/reactos/libs/sound/time.h @@ -16,6 +16,6 @@ VOID SleepMs(ULONG Milliseconds); ULONG -QuerySystemTimeMs(); +QuerySystemTimeMs(VOID); #endif diff --git a/reactos/lib/drivers/oskittcp/include/oskittcp.h b/reactos/lib/drivers/oskittcp/include/oskittcp.h index 64e587b7dad..c8f6066e65b 100644 --- a/reactos/lib/drivers/oskittcp/include/oskittcp.h +++ b/reactos/lib/drivers/oskittcp/include/oskittcp.h @@ -100,8 +100,8 @@ typedef struct _OSKITTCP_EVENT_HANDLERS { extern OSKITTCP_EVENT_HANDLERS OtcpEvent; -extern void InitOskitTCP(); -extern void DeinitOskitTCP(); +extern void InitOskitTCP( void ); +extern void DeinitOskitTCP( void ); extern void TimerOskitTCP( int FastTimer, int SlowTimer ); extern void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len ); extern int OskitTCPShutdown( void *socket, int disconn_type ); diff --git a/reactos/lib/fslib/vfatlib/check/io.h b/reactos/lib/fslib/vfatlib/check/io.h index 7b23462f515..518f00d49d3 100644 --- a/reactos/lib/fslib/vfatlib/check/io.h +++ b/reactos/lib/fslib/vfatlib/check/io.h @@ -21,7 +21,7 @@ void fs_open(PUNICODE_STRING DriveRoot,int rw); /* Opens the file system PATH. If RW is zero, the file system is opened read-only, otherwise, it is opened read-write. */ -BOOLEAN fs_isdirty(); +BOOLEAN fs_isdirty(void); /* Checks if filesystem is dirty */ @@ -55,7 +55,7 @@ NTSTATUS fs_lock(BOOLEAN LockVolume); /* Lock or unlocks the volume */ -void fs_dismount(); +void fs_dismount(void); /* Dismounts the volume */ diff --git a/reactos/lib/ppcmmu/mmuobject.h b/reactos/lib/ppcmmu/mmuobject.h index 024f757e38a..92e0486b186 100644 --- a/reactos/lib/ppcmmu/mmuobject.h +++ b/reactos/lib/ppcmmu/mmuobject.h @@ -1,6 +1,6 @@ #pragma once -void initme(); +void initme(void); void mmusetramsize(paddr_t size); int mmuaddpage(ppc_map_info_t *info, int count); void mmudelpage(ppc_map_info_t *info, int count); @@ -10,5 +10,5 @@ void *allocvsid(int); void mmuallocvsid(int vsid, int mask); void freevsid(int); void mmufreevsid(int vsid, int mask); -int mmunitest(); +int mmunitest(void); void callkernel(void *fun_ptr, void *arg); diff --git a/reactos/ntoskrnl/include/internal/amd64/ke.h b/reactos/ntoskrnl/include/internal/amd64/ke.h index ffb3f15c4b6..bbad6b89771 100644 --- a/reactos/ntoskrnl/include/internal/amd64/ke.h +++ b/reactos/ntoskrnl/include/internal/amd64/ke.h @@ -226,30 +226,30 @@ VOID FASTCALL KiInitializeTss(IN PKTSS Tss, IN UINT64 Stack); -VOID KiDivideErrorFault(); -VOID KiDebugTrapOrFault(); -VOID KiNmiInterrupt(); -VOID KiBreakpointTrap(); -VOID KiOverflowTrap(); -VOID KiBoundFault(); -VOID KiInvalidOpcodeFault(); -VOID KiNpxNotAvailableFault(); -VOID KiDoubleFaultAbort(); -VOID KiNpxSegmentOverrunAbort(); -VOID KiInvalidTssFault(); -VOID KiSegmentNotPresentFault(); -VOID KiStackFault(); -VOID KiGeneralProtectionFault(); -VOID KiPageFault(); -VOID KiFloatingErrorFault(); -VOID KiAlignmentFault(); -VOID KiMcheckAbort(); -VOID KiXmmException(); -VOID KiApcInterrupt(); -VOID KiRaiseAssertion(); -VOID KiDebugServiceTrap(); -VOID KiDpcInterrupt(); -VOID KiIpiInterrupt(); +VOID KiDivideErrorFault(VOID); +VOID KiDebugTrapOrFault(VOID); +VOID KiNmiInterrupt(VOID); +VOID KiBreakpointTrap(VOID); +VOID KiOverflowTrap(VOID); +VOID KiBoundFault(VOID); +VOID KiInvalidOpcodeFault(VOID); +VOID KiNpxNotAvailableFault(VOID); +VOID KiDoubleFaultAbort(VOID); +VOID KiNpxSegmentOverrunAbort(VOID); +VOID KiInvalidTssFault(VOID); +VOID KiSegmentNotPresentFault(VOID); +VOID KiStackFault(VOID); +VOID KiGeneralProtectionFault(VOID); +VOID KiPageFault(VOID); +VOID KiFloatingErrorFault(VOID); +VOID KiAlignmentFault(VOID); +VOID KiMcheckAbort(VOID); +VOID KiXmmException(VOID); +VOID KiApcInterrupt(VOID); +VOID KiRaiseAssertion(VOID); +VOID KiDebugServiceTrap(VOID); +VOID KiDpcInterrupt(VOID); +VOID KiIpiInterrupt(VOID); VOID KiGdtPrepareForApplicationProcessorInit(ULONG Id); @@ -284,7 +284,7 @@ KiGetFeatureBits(VOID); VOID NTAPI -KiInitializeCpuFeatures(); +KiInitializeCpuFeatures(VOID); ULONG KeAllocateGdtSelector(ULONG Desc[2]); VOID KeFreeGdtSelector(ULONG Entry); diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index 53ee9b0f4b2..5bb1060b548 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -245,7 +245,7 @@ KdpSafeWriteMemory( VOID NTAPI -KdpEnableSafeMem(); +KdpEnableSafeMem(VOID); /* KD GLOBALS ***************************************************************/ diff --git a/reactos/ntoskrnl/kdbg/kdb.h b/reactos/ntoskrnl/kdbg/kdb.h index d77cdb0aa88..1872377e96a 100644 --- a/reactos/ntoskrnl/kdbg/kdb.h +++ b/reactos/ntoskrnl/kdbg/kdb.h @@ -96,7 +96,7 @@ KdbpStackSwitchAndCall( extern PCHAR KdbInitFileBuffer; VOID -KdbpCliInit(); +KdbpCliInit(VOID); VOID KdbpCliMainLoop( @@ -107,7 +107,7 @@ KdbpCliModuleLoaded( IN PUNICODE_STRING Name); VOID -KdbpCliInterpretInitFile(); +KdbpCliInterpretInitFile(VOID); VOID KdbpPrint( @@ -260,6 +260,6 @@ DbgEnableFile(PCH Filename); VOID DbgDisableFile(PCH Filename); VOID -KbdDisableMouse(); +KbdDisableMouse(VOID); VOID -KbdEnableMouse(); +KbdEnableMouse(VOID); diff --git a/reactos/subsystems/win32/win32k/include/callback.h b/reactos/subsystems/win32/win32k/include/callback.h index 0b978a67e49..0494b99f36f 100644 --- a/reactos/subsystems/win32/win32k/include/callback.h +++ b/reactos/subsystems/win32/win32k/include/callback.h @@ -20,7 +20,7 @@ co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback, HMENU APIENTRY -co_IntLoadSysMenuTemplate(); +co_IntLoadSysMenuTemplate(VOID); BOOL APIENTRY co_IntLoadDefaultCursors(VOID); diff --git a/reactos/subsystems/win32/win32k/include/cursoricon.h b/reactos/subsystems/win32/win32k/include/cursoricon.h index 1a66dbc5408..0c0059a933d 100644 --- a/reactos/subsystems/win32/win32k/include/cursoricon.h +++ b/reactos/subsystems/win32/win32k/include/cursoricon.h @@ -61,8 +61,8 @@ typedef struct _SYSTEM_CURSORINFO BOOL ScreenSaverRunning; } SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO; -BOOL InitCursorImpl(); -PCURICON_OBJECT IntCreateCurIconHandle(); +BOOL InitCursorImpl(VOID); +PCURICON_OBJECT IntCreateCurIconHandle(VOID); VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process); BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, @@ -73,7 +73,7 @@ BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg); int UserShowCursor(BOOL bShow); -PSYSTEM_CURSORINFO IntGetSysCursorInfo(); +PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID); #define IntReleaseCurIconObject(CurIconObj) \ UserDereferenceObject(CurIconObj) diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index 1e85e364d35..caf112b827e 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -156,9 +156,9 @@ typedef struct _DC extern PDC defaultDCstate; -INIT_FUNCTION NTSTATUS NTAPI InitDcImpl(); +INIT_FUNCTION NTSTATUS NTAPI InitDcImpl(VOID); PPDEVOBJ FASTCALL IntEnumHDev(VOID); -PDC NTAPI DC_AllocDcWithHandle(); +PDC NTAPI DC_AllocDcWithHandle(VOID); VOID FASTCALL DC_InitDC(HDC DCToInit); VOID FASTCALL DC_AllocateDcAttr(HDC); VOID FASTCALL DC_FreeDcAttr(HDC); diff --git a/reactos/subsystems/win32/win32k/include/device.h b/reactos/subsystems/win32/win32k/include/device.h index 2ad19b278a7..dedae46c427 100644 --- a/reactos/subsystems/win32/win32k/include/device.h +++ b/reactos/subsystems/win32/win32k/include/device.h @@ -33,7 +33,7 @@ EngpRegisterGraphicsDevice( INIT_FUNCTION NTSTATUS NTAPI -InitDeviceImpl(); +InitDeviceImpl(VOID); BOOL FASTCALL diff --git a/reactos/subsystems/win32/win32k/include/gdidebug.h b/reactos/subsystems/win32/win32k/include/gdidebug.h index 944e546c118..ffea26dcdc9 100644 --- a/reactos/subsystems/win32/win32k/include/gdidebug.h +++ b/reactos/subsystems/win32/win32k/include/gdidebug.h @@ -19,8 +19,8 @@ enum _DEBUGCHANNELS void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable); ULONG CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture); -BOOL GdiDbgHTIntegrityCheck(); -void GdiDbgDumpLockedHandles(); +BOOL GdiDbgHTIntegrityCheck(VOID); +void GdiDbgDumpLockedHandles(VOID); #define DBGENABLE(ch) gulDebugChannels |= (ch); #define DBGDISABLE(ch) gulDebugChannels &= ~(ch); diff --git a/reactos/subsystems/win32/win32k/include/gdiobj.h b/reactos/subsystems/win32/win32k/include/gdiobj.h index 3f581bca22f..e29077c2f42 100644 --- a/reactos/subsystems/win32/win32k/include/gdiobj.h +++ b/reactos/subsystems/win32/win32k/include/gdiobj.h @@ -83,7 +83,7 @@ PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCES INIT_FUNCTION NTSTATUS NTAPI -InitGdiHandleTable(); +InitGdiHandleTable(VOID); #define GDIOBJ_GetObjectType(Handle) \ GDI_HANDLE_GET_TYPE(Handle) diff --git a/reactos/subsystems/win32/win32k/include/input.h b/reactos/subsystems/win32/win32k/include/input.h index 60056046d1a..167c2af5aad 100644 --- a/reactos/subsystems/win32/win32k/include/input.h +++ b/reactos/subsystems/win32/win32k/include/input.h @@ -45,7 +45,7 @@ BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt); BOOL FASTCALL IntMouseInput(MOUSEINPUT *mi); BOOL FASTCALL IntKeyboardInput(KEYBDINPUT *ki); -BOOL UserInitDefaultKeyboardLayout(); +BOOL UserInitDefaultKeyboardLayout(VOID); PKBL UserHklToKbl(HKL hKl); BOOL FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL); BOOL FASTCALL IntConnectThreadInput(PTHREADINFO,PTHREADINFO*,PUSER_MESSAGE_QUEUE*); diff --git a/reactos/subsystems/win32/win32k/include/ldevobj.h b/reactos/subsystems/win32/win32k/include/ldevobj.h index 6bae83ab8a0..963b8332492 100644 --- a/reactos/subsystems/win32/win32k/include/ldevobj.h +++ b/reactos/subsystems/win32/win32k/include/ldevobj.h @@ -66,7 +66,7 @@ LDEVOBJ_pdmiGetModes( INIT_FUNCTION NTSTATUS NTAPI -InitLDEVImpl(); +InitLDEVImpl(VOID); PLDEVOBJ APIENTRY diff --git a/reactos/subsystems/win32/win32k/include/monitor.h b/reactos/subsystems/win32/win32k/include/monitor.h index 729f28d0a91..280864fb7cb 100644 --- a/reactos/subsystems/win32/win32k/include/monitor.h +++ b/reactos/subsystems/win32/win32k/include/monitor.h @@ -35,8 +35,8 @@ typedef struct _MONITOR INIT_FUNCTION NTSTATUS NTAPI -InitMonitorImpl(); -NTSTATUS CleanupMonitorImpl(); +InitMonitorImpl(VOID); +NTSTATUS CleanupMonitorImpl(VOID); NTSTATUS IntAttachMonitor(PDEVOBJ *pGdiDevice, ULONG DisplayNumber); NTSTATUS IntDetachMonitor(PDEVOBJ *pGdiDevice); diff --git a/reactos/subsystems/win32/win32k/include/msgqueue.h b/reactos/subsystems/win32/win32k/include/msgqueue.h index 84d803bb7fb..f078a16f23d 100644 --- a/reactos/subsystems/win32/win32k/include/msgqueue.h +++ b/reactos/subsystems/win32/win32k/include/msgqueue.h @@ -227,8 +227,8 @@ MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd); __inline BOOL MsqIsSignaled( PUSER_MESSAGE_QUEUE queue ); __inline VOID MsqSetQueueBits( PUSER_MESSAGE_QUEUE queue, WORD bits ); -BOOL APIENTRY IntInitMessagePumpHook(); -BOOL APIENTRY IntUninitMessagePumpHook(); +BOOL APIENTRY IntInitMessagePumpHook(VOID); +BOOL APIENTRY IntUninitMessagePumpHook(VOID); #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)) LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam); diff --git a/reactos/subsystems/win32/win32k/include/palette.h b/reactos/subsystems/win32/win32k/include/palette.h index d18edee49df..10d6dffbae6 100644 --- a/reactos/subsystems/win32/win32k/include/palette.h +++ b/reactos/subsystems/win32/win32k/include/palette.h @@ -74,7 +74,7 @@ HPALETTE FASTCALL PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, GDIOBJ_ShareUnlockObjByPtr(&ppal->BaseObject) BOOL INTERNAL_CALL PALETTE_Cleanup(PVOID ObjectBody); -INIT_FUNCTION NTSTATUS NTAPI InitPaletteImpl(); +INIT_FUNCTION NTSTATUS NTAPI InitPaletteImpl(VOID); VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size); INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); diff --git a/reactos/subsystems/win32/win32k/include/pdevobj.h b/reactos/subsystems/win32/win32k/include/pdevobj.h index bece851460a..34297add5f4 100644 --- a/reactos/subsystems/win32/win32k/include/pdevobj.h +++ b/reactos/subsystems/win32/win32k/include/pdevobj.h @@ -177,7 +177,7 @@ PDEVOBJ_vGetDeviceCaps( INIT_FUNCTION NTSTATUS NTAPI -InitPDEVImpl(); +InitPDEVImpl(VOID); PSIZEL FASTCALL From 22cb80d434c0bd8e5e2dd7de56f06f6247113f8e Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 17 Mar 2011 10:59:54 +0000 Subject: [PATCH 18/90] [NTDLL/LDR] - Fix a typo in LdrQueryProcessModuleInformationEx(). - Stub LdrpEnsureLoaderLockIsHeld() for now. - Improve LdrpRunInitializeRoutines() and enable it (just compiling, it's not in the running path of the code yet). - Fix an uninit var warning in ldrpe.c - Implement LdrpClearLoadInProgress(). - Rename "ExeModule" to a more consistent LdrpImageEntry. svn path=/trunk/; revision=51079 --- reactos/dll/ntdll/ldr/ldrapi.c | 2 +- reactos/dll/ntdll/ldr/ldrinit.c | 42 +++++++++++++++++++++++--------- reactos/dll/ntdll/ldr/ldrpe.c | 2 +- reactos/dll/ntdll/ldr/ldrutils.c | 31 +++++++++++++++++++++++ reactos/dll/ntdll/ldr/startup.c | 36 +++++++++++++-------------- reactos/dll/ntdll/ldr/utils.c | 16 ++++++------ 6 files changed, 89 insertions(+), 40 deletions(-) diff --git a/reactos/dll/ntdll/ldr/ldrapi.c b/reactos/dll/ntdll/ldr/ldrapi.c index af898d035e5..0a19351dab8 100644 --- a/reactos/dll/ntdll/ldr/ldrapi.c +++ b/reactos/dll/ntdll/ldr/ldrapi.c @@ -461,7 +461,7 @@ LdrQueryProcessModuleInformationEx(IN ULONG ProcessId, while (InitEntry != InitListHead) { - InitModule = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); + InitModule = CONTAINING_RECORD(InitEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); /* Increase the index */ ModulePtr->InitOrderIndex++; diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index bd15a66cbea..e832276657e 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -23,6 +23,9 @@ UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); BOOLEAN LdrpInLdrInit; PLDR_DATA_TABLE_ENTRY LdrpImageEntry; +PUNICODE_STRING LdrpTopLevelDllBeingLoaded; +extern PTEB LdrpTopLevelDllBeingLoadedTeb; // defined in rtlsupp.c! +PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer; //RTL_BITMAP TlsBitMap; //RTL_BITMAP TlsExpansionBitMap; @@ -333,11 +336,17 @@ LdrQueryImageFileExecutionOptions(IN PUNICODE_STRING SubKey, FALSE); } +VOID +NTAPI +LdrpEnsureLoaderLockIsHeld() +{ + // Ignored atm +} + NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) { -#if 0 PLDR_DATA_TABLE_ENTRY LocalArray[16]; PLIST_ENTRY ListHead; PLIST_ENTRY NextEntry; @@ -350,6 +359,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx; ULONG BreakOnDllLoad; PTEB OldTldTeb; + BOOLEAN DllStatus; DPRINT1("LdrpRunInitializeRoutines() called for %wZ\n", &LdrpImageEntry->BaseDllName); @@ -493,7 +503,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) if (ShowSnaps) { DPRINT1("LDR: %wZ loaded.", &LdrEntry->BaseDllName); - DPRINT1(" - About to call init routine at %lx\n", EntryPoint); + DPRINT1(" - About to call init routine at %p\n", EntryPoint); } /* Break in debugger */ @@ -526,10 +536,10 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) /* Call the Entrypoint */ DPRINT1("%wZ - Calling entry point at %x for thread attaching\n", &LdrEntry->BaseDllName, EntryPoint); - LdrpCallDllEntry(EntryPoint, - LdrEntry->DllBase, - DLL_PROCESS_ATTACH, - Context); + DllStatus = LdrpCallDllEntry(EntryPoint, + LdrEntry->DllBase, + DLL_PROCESS_ATTACH, + Context); /* Deactivate the ActCtx */ RtlDeactivateActivationContextUnsafeFast(&ActCtx); @@ -539,6 +549,16 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) /* Mark the entry as processed */ LdrEntry->Flags |= LDRP_PROCESS_ATTACH_CALLED; + + /* Fail if DLL init failed */ + if (!DllStatus) + { + DPRINT1("LDR: DLL_PROCESS_ATTACH for dll \"%wZ\" (InitRoutine: %p) failed\n", + &LdrEntry->BaseDllName, EntryPoint); + + Status = STATUS_DLL_INIT_FAILED; + goto Quickie; + } } } @@ -551,6 +571,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); /* FIXME: Verify NX Compat */ + // LdrpCheckNXCompatibility() /* Next entry */ NextEntry = NextEntry->Flink; @@ -569,12 +590,13 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) LdrpImageEntry->EntryPointActivationContext); /* Do TLS callbacks */ - LdrpTlsCallback(Peb->ImageBaseAddress, DLL_PROCESS_DETACH); + LdrpTlsCallback(Peb->ImageBaseAddress, DLL_PROCESS_ATTACH); /* Deactivate the ActCtx */ RtlDeactivateActivationContextUnsafeFast(&ActCtx); } +Quickie: /* Restore old TEB */ LdrpTopLevelDllBeingLoadedTeb = OldTldTeb; @@ -586,12 +608,8 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) } /* Return to caller */ - DPRINT("LdrpAttachProcess() done\n"); + DPRINT("LdrpRunInitializeRoutines() done\n"); return Status; -#else - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -#endif } NTSTATUS diff --git a/reactos/dll/ntdll/ldr/ldrpe.c b/reactos/dll/ntdll/ldr/ldrpe.c index 129f756c862..4e72d91e908 100644 --- a/reactos/dll/ntdll/ldr/ldrpe.c +++ b/reactos/dll/ntdll/ldr/ldrpe.c @@ -59,7 +59,7 @@ LdrpSnapThunk(IN PVOID ExportBase, PIMAGE_IMPORT_BY_NAME AddressOfData; PULONG NameTable; PUSHORT OrdinalTable; - LPSTR ImportName; + LPSTR ImportName = NULL; USHORT Hint; NTSTATUS Status; ULONG_PTR HardErrorParameters[3]; diff --git a/reactos/dll/ntdll/ldr/ldrutils.c b/reactos/dll/ntdll/ldr/ldrutils.c index 5c37694807c..87ae93b2be6 100644 --- a/reactos/dll/ntdll/ldr/ldrutils.c +++ b/reactos/dll/ntdll/ldr/ldrutils.c @@ -326,4 +326,35 @@ LdrpLoadDll(IN BOOLEAN Redirected, return STATUS_NOT_IMPLEMENTED; } +ULONG +NTAPI +LdrpClearLoadInProgress() +{ + PLIST_ENTRY ListHead; + PLIST_ENTRY Entry; + PLDR_DATA_TABLE_ENTRY Module; + ULONG ModulesCount = 0; + + /* Traverse the init list */ + ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList; + Entry = ListHead->Flink; + + while (Entry != ListHead) + { + Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); + + /* Clear load in progress flag */ + Module->Flags &= ~LDRP_LOAD_IN_PROGRESS; + + /* Increase counter for modules with entry point count but not processed yet */ + if (Module->EntryPoint && + !(Module->Flags & LDRP_ENTRY_PROCESSED)) ModulesCount++; + + /* Advance to the next entry */ + Entry = Entry->Flink; + } + + return ModulesCount; +} + /* EOF */ diff --git a/reactos/dll/ntdll/ldr/startup.c b/reactos/dll/ntdll/ldr/startup.c index fb814c499f2..774f4495d50 100644 --- a/reactos/dll/ntdll/ldr/startup.c +++ b/reactos/dll/ntdll/ldr/startup.c @@ -23,7 +23,7 @@ extern PTEB LdrpTopLevelDllBeingLoadedTeb; /* GLOBALS *******************************************************************/ -PLDR_DATA_TABLE_ENTRY ExeModule; +extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry; static RTL_CRITICAL_SECTION PebLock; static RTL_BITMAP TlsBitMap; static RTL_BITMAP TlsExpansionBitMap; @@ -526,17 +526,17 @@ LdrpInit2(PCONTEXT Context, &NtModule->InInitializationOrderModuleList); /* add entry for executable (becomes first list entry) */ - ExeModule = (PLDR_DATA_TABLE_ENTRY) + LdrpImageEntry = (PLDR_DATA_TABLE_ENTRY) RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(LDR_DATA_TABLE_ENTRY)); - if (ExeModule == NULL) + if (LdrpImageEntry == NULL) { DPRINT1("Failed to create loader module infomation\n"); ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES); } - ExeModule->DllBase = Peb->ImageBaseAddress; + LdrpImageEntry->DllBase = Peb->ImageBaseAddress; if ((Peb->ProcessParameters == NULL) || (Peb->ProcessParameters->ImagePathName.Length == 0)) @@ -545,32 +545,32 @@ LdrpInit2(PCONTEXT Context, ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL); } - RtlCreateUnicodeString(&ExeModule->FullDllName, + RtlCreateUnicodeString(&LdrpImageEntry->FullDllName, Peb->ProcessParameters->ImagePathName.Buffer); - RtlCreateUnicodeString(&ExeModule->BaseDllName, - wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1); + RtlCreateUnicodeString(&LdrpImageEntry->BaseDllName, + wcsrchr(LdrpImageEntry->FullDllName.Buffer, L'\\') + 1); - DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n", &ExeModule->BaseDllName, &ExeModule->FullDllName); + DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n", &LdrpImageEntry->BaseDllName, &LdrpImageEntry->FullDllName); - ExeModule->Flags = LDRP_ENTRY_PROCESSED; - ExeModule->LoadCount = -1; /* don't unload */ - ExeModule->TlsIndex = -1; - ExeModule->SectionPointer = NULL; - ExeModule->CheckSum = 0; + LdrpImageEntry->Flags = LDRP_ENTRY_PROCESSED; + LdrpImageEntry->LoadCount = -1; /* don't unload */ + LdrpImageEntry->TlsIndex = -1; + LdrpImageEntry->SectionPointer = NULL; + LdrpImageEntry->CheckSum = 0; - NTHeaders = RtlImageNtHeader(ExeModule->DllBase); - ExeModule->SizeOfImage = LdrpGetResidentSize(NTHeaders); - ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp; + NTHeaders = RtlImageNtHeader(LdrpImageEntry->DllBase); + LdrpImageEntry->SizeOfImage = LdrpGetResidentSize(NTHeaders); + LdrpImageEntry->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp; LdrpTopLevelDllBeingLoadedTeb = NtCurrentTeb(); InsertHeadList(&Peb->Ldr->InLoadOrderModuleList, - &ExeModule->InLoadOrderLinks); + &LdrpImageEntry->InLoadOrderLinks); LdrpInitLoader(); EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL); - ExeModule->EntryPoint = EntryPoint; + LdrpImageEntry->EntryPoint = EntryPoint; /* all required dlls are loaded now */ Peb->Ldr->Initialized = TRUE; diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 232a6ef7f6b..7ed646ff494 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -35,7 +35,7 @@ static BOOLEAN LdrpDllShutdownInProgress = FALSE; static HANDLE LdrpKnownDllsDirHandle = NULL; static UNICODE_STRING LdrpKnownDllPath = {0, 0, NULL}; static PLDR_DATA_TABLE_ENTRY LdrpLastModule = NULL; -extern PLDR_DATA_TABLE_ENTRY ExeModule; +extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry; /* PROTOTYPES ****************************************************************/ @@ -222,7 +222,7 @@ LdrpInitLoader(VOID) ULONG Length; NTSTATUS Status; - DPRINT("LdrpInitLoader() called for %wZ\n", &ExeModule->BaseDllName); + DPRINT("LdrpInitLoader() called for %wZ\n", &LdrpImageEntry->BaseDllName); /* Get handle to the 'KnownDlls' directory */ RtlInitUnicodeString(&Name, @@ -865,7 +865,7 @@ LdrFindEntryForName(PUNICODE_STRING Name, // NULL is the current process if (Name == NULL) { - *Module = ExeModule; + *Module = LdrpImageEntry; RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); return(STATUS_SUCCESS); } @@ -2416,7 +2416,7 @@ LdrGetDllHandle(IN PWSTR DllPath OPTIONAL, /* NULL is the current executable */ if (DllName == NULL) { - *DllHandle = ExeModule->DllBase; + *DllHandle = LdrpImageEntry->DllBase; DPRINT("BaseAddress 0x%lx\n", *DllHandle); return STATUS_SUCCESS; } @@ -2560,7 +2560,7 @@ LdrpDetachProcess(BOOLEAN UnloadAll) static ULONG CallingCount = 0; DPRINT("LdrpDetachProcess() called for %wZ\n", - &ExeModule->BaseDllName); + &LdrpImageEntry->BaseDllName); if (UnloadAll) LdrpDllShutdownInProgress = TRUE; @@ -2672,7 +2672,7 @@ LdrpAttachProcess(VOID) NTSTATUS Status = STATUS_SUCCESS; DPRINT("LdrpAttachProcess() called for %wZ\n", - &ExeModule->BaseDllName); + &LdrpImageEntry->BaseDllName); ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList; Entry = ModuleListHead->Flink; @@ -2752,7 +2752,7 @@ LdrpAttachThread (VOID) NTSTATUS Status; DPRINT("LdrpAttachThread() called for %wZ\n", - &ExeModule->BaseDllName); + &LdrpImageEntry->BaseDllName); RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); @@ -2810,7 +2810,7 @@ LdrShutdownThread (VOID) PLDR_DATA_TABLE_ENTRY Module; DPRINT("LdrShutdownThread() called for %wZ\n", - &ExeModule->BaseDllName); + &LdrpImageEntry->BaseDllName); RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); From bfb74cd0bc425dbbe70574e0859e79087c06fe4c Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 17 Mar 2011 11:20:16 +0000 Subject: [PATCH 19/90] - Fix build. svn path=/trunk/; revision=51080 --- reactos/dll/ntdll/include/ntdllp.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index dc24500068e..c882ef0e263 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -60,6 +60,9 @@ LdrpLoadDll(IN BOOLEAN Redirected, OUT PVOID *BaseAddress, IN BOOLEAN CallInit); +ULONG NTAPI +LdrpClearLoadInProgress(); + /* FIXME: Cleanup this mess */ typedef NTSTATUS (NTAPI *PEPFUNC)(PPEB); NTSTATUS LdrMapSections(HANDLE ProcessHandle, From 71201dea2c990f58efb7ef6971bb9d96f05f3f43 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Thu, 17 Mar 2011 13:19:18 +0000 Subject: [PATCH 20/90] [win32k] - Improve the definition and simplify NtUserCreateDesktop, NtUserOpenDesktop, NtUserCreateWindowStation, NtUserOpenWindowStation svn path=/trunk/; revision=51082 --- reactos/dll/win32/user32/misc/desktop.c | 17 +- reactos/dll/win32/user32/misc/winsta.c | 88 ++++++- reactos/include/reactos/win32k/ntuser.h | 14 +- .../subsystems/win32/win32k/ntuser/desktop.c | 220 ++++-------------- .../subsystems/win32/win32k/ntuser/winsta.c | 144 ++++-------- 5 files changed, 184 insertions(+), 299 deletions(-) diff --git a/reactos/dll/win32/user32/misc/desktop.c b/reactos/dll/win32/user32/misc/desktop.c index e6ee527d274..1a317beb3f3 100644 --- a/reactos/dll/win32/user32/misc/desktop.c +++ b/reactos/dll/win32/user32/misc/desktop.c @@ -564,13 +564,22 @@ OpenDesktopW( ACCESS_MASK dwDesiredAccess) { UNICODE_STRING DesktopName; + OBJECT_ATTRIBUTES ObjectAttributes; RtlInitUnicodeString(&DesktopName, lpszDesktop); - return NtUserOpenDesktop( - &DesktopName, - dwFlags, - dwDesiredAccess); + InitializeObjectAttributes(&ObjectAttributes, + &DesktopName, + OBJ_CASE_INSENSITIVE, + GetProcessWindowStation(), + 0); + + if( fInherit == TRUE ) + { + ObjectAttributes.Attributes |= OBJ_INHERIT; + } + + return NtUserOpenDesktop(&ObjectAttributes, dwFlags, dwDesiredAccess); } diff --git a/reactos/dll/win32/user32/misc/winsta.c b/reactos/dll/win32/user32/misc/winsta.c index f6f237c2a74..b38732ddf07 100644 --- a/reactos/dll/win32/user32/misc/winsta.c +++ b/reactos/dll/win32/user32/misc/winsta.c @@ -12,6 +12,7 @@ #include #include +WINE_DEFAULT_DEBUG_CHANNEL(winsta); /* @@ -58,12 +59,50 @@ CreateWindowStationW(LPCWSTR lpwinsta, LPSECURITY_ATTRIBUTES lpsa) { UNICODE_STRING WindowStationName; + UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hWindowStationsDir; + NTSTATUS Status; + HWINSTA hwinsta; + + /* Open WindowStations directory */ + InitializeObjectAttributes(&ObjectAttributes, + &WindowStationsDir, + OBJ_CASE_INSENSITIVE, + 0, + 0); + + Status = NtOpenDirectoryObject(&hWindowStationsDir, + DIRECTORY_CREATE_OBJECT, + &ObjectAttributes); + if(!NT_SUCCESS(Status)) + { + ERR("Failed to open WindowStations directory\n"); + return NULL; + } RtlInitUnicodeString(&WindowStationName, lpwinsta); - return NtUserCreateWindowStation(&WindowStationName, - dwDesiredAccess, - lpsa, 0, 0, 0, 0); + /* Create the window station object */ + InitializeObjectAttributes(&ObjectAttributes, + &WindowStationName, + OBJ_CASE_INSENSITIVE, + hWindowStationsDir, + 0); + + /* Check if the handle should be inheritable */ + if (lpsa && lpsa->bInheritHandle) + { + ObjectAttributes.Attributes |= OBJ_INHERIT; + } + + hwinsta = NtUserCreateWindowStation(&ObjectAttributes, + dwDesiredAccess, + 0, 0, 0, 0, 0); + + NtClose(hWindowStationsDir); + + return hwinsta; } /* @@ -299,14 +338,51 @@ OpenWindowStationA(LPCSTR lpszWinSta, */ HWINSTA WINAPI OpenWindowStationW(LPCWSTR lpszWinSta, - BOOL fInherit, - ACCESS_MASK dwDesiredAccess) + BOOL fInherit, + ACCESS_MASK dwDesiredAccess) { UNICODE_STRING WindowStationName; + UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hWindowStationsDir; + NTSTATUS Status; + HWINSTA hwinsta; + /* Open WindowStations directory */ + InitializeObjectAttributes(&ObjectAttributes, + &WindowStationsDir, + OBJ_CASE_INSENSITIVE, + 0, + 0); + + Status = NtOpenDirectoryObject(&hWindowStationsDir, + DIRECTORY_TRAVERSE, + &ObjectAttributes); + if(!NT_SUCCESS(Status)) + { + ERR("Failed to open WindowStations directory\n"); + return NULL; + } + + /* Open the window station object */ RtlInitUnicodeString(&WindowStationName, lpszWinSta); - return NtUserOpenWindowStation(&WindowStationName, dwDesiredAccess); + InitializeObjectAttributes(&ObjectAttributes, + &WindowStationName, + OBJ_CASE_INSENSITIVE, + hWindowStationsDir, + 0); + + if( fInherit == TRUE ) + { + ObjectAttributes.Attributes |= OBJ_INHERIT; + } + + hwinsta = NtUserOpenWindowStation(&ObjectAttributes, dwDesiredAccess); + + NtClose(hWindowStationsDir); + + return hwinsta; } diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index b0e800bacdb..d9f28d6fa0e 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -1462,7 +1462,7 @@ NtUserCreateLocalMemHandle( HWND NTAPI NtUserCreateWindowEx( - DWORD dwExStyle, // |= 0x80000000 == Ansi used to set WNDS_ANSICREATOR + DWORD dwExStyle, PLARGE_STRING plstrClassName, PLARGE_STRING plstrClsVersion, PLARGE_STRING plstrWindowName, @@ -1481,9 +1481,9 @@ NtUserCreateWindowEx( HWINSTA NTAPI NtUserCreateWindowStation( - PUNICODE_STRING lpszWindowStationName, + POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpSecurity, + DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, @@ -2301,9 +2301,9 @@ NtUserOpenClipboard( HDESK NTAPI NtUserOpenDesktop( - PUNICODE_STRING lpszDesktopName, - DWORD dwFlags, - ACCESS_MASK dwDesiredAccess); + POBJECT_ATTRIBUTES ObjectAttributes, + DWORD dwFlags, + ACCESS_MASK dwDesiredAccess); HDESK NTAPI @@ -2315,7 +2315,7 @@ NtUserOpenInputDesktop( HWINSTA NTAPI NtUserOpenWindowStation( - PUNICODE_STRING lpszWindowStationName, + POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess); BOOL diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index 1653bc21494..c2d1c29f7bb 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -859,15 +859,12 @@ IntFreeDesktopHeap(IN OUT PDESKTOP Desktop) HDESK APIENTRY NtUserCreateDesktop( - POBJECT_ATTRIBUTES poa, + POBJECT_ATTRIBUTES ObjectAttributes, PUNICODE_STRING lpszDesktopDevice, LPDEVMODEW lpdmw, DWORD dwFlags, ACCESS_MASK dwDesiredAccess) { - OBJECT_ATTRIBUTES ObjectAttributes; - PTHREADINFO W32Thread; - PWINSTATION_OBJECT WinStaObject; PDESKTOP DesktopObject; UNICODE_STRING DesktopName; NTSTATUS Status = STATUS_SUCCESS; @@ -875,12 +872,9 @@ NtUserCreateDesktop( CSR_API_MESSAGE Request; PVOID DesktopHeapSystemBase = NULL; SIZE_T DesktopInfoSize; - UNICODE_STRING SafeDesktopName; ULONG DummyContext; ULONG_PTR HeapSize = 4 * 1024 * 1024; /* FIXME */ - HWINSTA hWindowStation = NULL ; - PUNICODE_STRING lpszDesktopName = NULL; - UNICODE_STRING ClassName, MenuName; + UNICODE_STRING ClassName; LARGE_STRING WindowName; BOOL NoHooks = FALSE; PWND pWnd = NULL; @@ -889,7 +883,7 @@ NtUserCreateDesktop( PTHREADINFO ptiCurrent; DECLARE_RETURN(HDESK); - DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName); + DPRINT("Enter NtUserCreateDesktop\n"); UserEnterExclusive(); ptiCurrent = PsGetCurrentThreadWin32Thread(); @@ -899,19 +893,38 @@ NtUserCreateDesktop( NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS); ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS; } + DesktopName.Buffer = NULL; + /* + * Try to open already existing desktop + */ + + DPRINT("Trying to open desktop (%wZ)\n", &DesktopName); + + Status = ObOpenObjectByName( + ObjectAttributes, + ExDesktopObjectType, + UserMode, + NULL, + dwDesiredAccess, + (PVOID)&DummyContext, + (HANDLE*)&Desktop); + if (!NT_SUCCESS(Status)) RETURN(NULL); + if (Status == STATUS_OBJECT_NAME_EXISTS) + { + RETURN( Desktop); + } + + /* Capture desktop name */ _SEH2_TRY { - ProbeForRead( poa, - sizeof(OBJECT_ATTRIBUTES), - 1); + ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1); - hWindowStation = poa->RootDirectory; - lpszDesktopName = poa->ObjectName; + Status = IntSafeCopyUnicodeString(&DesktopName, ObjectAttributes->ObjectName); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status =_SEH2_GetExceptionCode(); + Status = _SEH2_GetExceptionCode(); } _SEH2_END @@ -922,75 +935,6 @@ NtUserCreateDesktop( RETURN( NULL); } - Status = IntValidateWindowStationHandle( - hWindowStation, - KernelMode, - 0, /* FIXME - WINSTA_CREATEDESKTOP */ - &WinStaObject); - - if (! NT_SUCCESS(Status)) - { - DPRINT1("Failed validation of window station handle (0x%X), cannot create desktop %wZ\n", - hWindowStation, lpszDesktopName); - SetLastNtError(Status); - RETURN( NULL); - } - if(lpszDesktopName != NULL) - { - Status = IntSafeCopyUnicodeString(&SafeDesktopName, lpszDesktopName); - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( NULL); - } - } - else - { - RtlInitUnicodeString(&SafeDesktopName, NULL); - } - - if (! IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name, - &SafeDesktopName)) - { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - ObDereferenceObject(WinStaObject); - if (lpszDesktopName) - ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING); - RETURN( NULL); - } - if (lpszDesktopName) - ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING); - ObDereferenceObject(WinStaObject); - - /* - * Try to open already existing desktop - */ - - DPRINT("Trying to open desktop (%wZ)\n", &DesktopName); - - /* Initialize ObjectAttributes for the desktop object */ - InitializeObjectAttributes( - &ObjectAttributes, - &DesktopName, - 0, - NULL, - NULL); - - Status = ObOpenObjectByName( - &ObjectAttributes, - ExDesktopObjectType, - KernelMode, - NULL, - dwDesiredAccess, - (PVOID)&DummyContext, - (HANDLE*)&Desktop); - if (!NT_SUCCESS(Status)) RETURN(NULL); - if (Status == STATUS_OBJECT_NAME_EXISTS) - { - ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING); - RETURN( Desktop); - } - /* Reference the desktop */ Status = ObReferenceObjectByHandle(Desktop, 0, @@ -1011,12 +955,11 @@ NtUserCreateDesktop( RETURN(NULL); } - DesktopInfoSize = FIELD_OFFSET(DESKTOPINFO, - szDesktopName[(lpszDesktopName->Length / sizeof(WCHAR)) + 1]); + DesktopInfoSize = sizeof(DESKTOPINFO) + DesktopName.Length; DesktopObject->pDeskInfo = RtlAllocateHeap(DesktopObject->pheapDesktop, - HEAP_NO_SERIALIZE, - DesktopInfoSize); + HEAP_NO_SERIALIZE, + DesktopInfoSize); if (DesktopObject->pDeskInfo == NULL) { @@ -1031,8 +974,8 @@ NtUserCreateDesktop( DesktopObject->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase; DesktopObject->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize); RtlCopyMemory(DesktopObject->pDeskInfo->szDesktopName, - lpszDesktopName->Buffer, - lpszDesktopName->Length); + DesktopName.Buffer, + DesktopName.Length); /* Initialize some local (to win32k) desktop state. */ InitializeListHead(&DesktopObject->PtiList); @@ -1042,7 +985,6 @@ NtUserCreateDesktop( { InitializeListHead(&DesktopObject->pDeskInfo->aphkStart[i]); } - ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING); //// why is this here? #if 0 @@ -1090,7 +1032,6 @@ NtUserCreateDesktop( // ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_DESKTOP]))); ClassName.Length = 0; - RtlZeroMemory(&MenuName, sizeof(MenuName)); RtlZeroMemory(&WindowName, sizeof(WindowName)); RtlZeroMemory(&Cs, sizeof(Cs)); @@ -1113,9 +1054,8 @@ NtUserCreateDesktop( DesktopObject->pDeskInfo->spwnd = pWndDesktop; } #endif - W32Thread = PsGetCurrentThreadWin32Thread(); - if (!W32Thread->rpdesk) IntSetThreadDesktop(DesktopObject,FALSE); + if (!ptiCurrent->rpdesk) IntSetThreadDesktop(DesktopObject,FALSE); /* Based on wine/server/window.c in get_desktop_window. @@ -1123,7 +1063,6 @@ NtUserCreateDesktop( ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_HWNDMESSAGE]))); ClassName.Length = 0; - RtlZeroMemory(&MenuName, sizeof(MenuName)); RtlZeroMemory(&WindowName, sizeof(WindowName)); RtlZeroMemory(&Cs, sizeof(Cs)); @@ -1154,6 +1093,10 @@ NtUserCreateDesktop( RETURN( Desktop); CLEANUP: + if(DesktopName.Buffer != NULL) + { + ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING); + } if (!NoHooks && ptiCurrent) ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS; DPRINT("Leave NtUserCreateDesktop, ret=%i\n",_ret_); UserLeave(); @@ -1184,85 +1127,17 @@ CLEANUP: HDESK APIENTRY NtUserOpenDesktop( - PUNICODE_STRING lpszDesktopName, + POBJECT_ATTRIBUTES ObjectAttributes, DWORD dwFlags, ACCESS_MASK dwDesiredAccess) { - OBJECT_ATTRIBUTES ObjectAttributes; - HWINSTA WinSta; - PWINSTATION_OBJECT WinStaObject; - UNICODE_STRING DesktopName; - UNICODE_STRING SafeDesktopName; NTSTATUS Status; HDESK Desktop; - BOOL Result; - DECLARE_RETURN(HDESK); - - DPRINT("Enter NtUserOpenDesktop: %wZ\n", lpszDesktopName); - UserEnterExclusive(); - - /* - * Validate the window station handle and compose the fully - * qualified desktop name - */ - - WinSta = UserGetProcessWindowStation(); - Status = IntValidateWindowStationHandle( - WinSta, - KernelMode, - 0, - &WinStaObject); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed validation of window station handle (0x%X)\n", WinSta); - SetLastNtError(Status); - RETURN( 0); - } - - if(lpszDesktopName != NULL) - { - Status = IntSafeCopyUnicodeString(&SafeDesktopName, lpszDesktopName); - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( NULL); - } - } - else - { - RtlInitUnicodeString(&SafeDesktopName, NULL); - } - - Result = IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name, - &SafeDesktopName); - - if (lpszDesktopName) - ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING); - ObDereferenceObject(WinStaObject); - - - if (!Result) - { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - RETURN( 0); - } - - - DPRINT("Trying to open desktop (%wZ)\n", &DesktopName); - - /* Initialize ObjectAttributes for the desktop object */ - InitializeObjectAttributes( - &ObjectAttributes, - &DesktopName, - 0, - NULL, - NULL); Status = ObOpenObjectByName( - &ObjectAttributes, + ObjectAttributes, ExDesktopObjectType, - KernelMode, + UserMode, NULL, dwDesiredAccess, NULL, @@ -1271,19 +1146,10 @@ NtUserOpenDesktop( if (!NT_SUCCESS(Status)) { SetLastNtError(Status); - ExFreePool(DesktopName.Buffer); - RETURN( 0); + return 0; } - DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName); - ExFreePool(DesktopName.Buffer); - - RETURN( Desktop); - -CLEANUP: - DPRINT("Leave NtUserOpenDesktop, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; + return Desktop; } /* diff --git a/reactos/subsystems/win32/win32k/ntuser/winsta.c b/reactos/subsystems/win32/win32k/ntuser/winsta.c index ff429a17524..d4f4643f4ed 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winsta.c +++ b/reactos/subsystems/win32/win32k/ntuser/winsta.c @@ -392,61 +392,23 @@ IntGetScreenDC(VOID) HWINSTA APIENTRY NtUserCreateWindowStation( - PUNICODE_STRING lpszWindowStationName, + POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpSecurity, + DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6) { UNICODE_STRING WindowStationName; - UNICODE_STRING FullWindowStationName; PWINSTATION_OBJECT WindowStationObject; HWINSTA WindowStation; - OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; - /* - * Generate full window station name - */ - Status = ProbeAndCaptureUnicodeString(&WindowStationName, - UserMode, - lpszWindowStationName); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to capture window station name (status 0x%08x)\n", - Status); - SetLastNtError(Status); - return 0; - } - if (!IntGetFullWindowStationName(&FullWindowStationName, - &WindowStationName, - NULL)) - { - ReleaseCapturedUnicodeString(&WindowStationName, UserMode); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return 0; - } - - /* - * Try to open already existing window station - */ - - DPRINT("Trying to open window station (%wZ)\n", &FullWindowStationName); - - /* Initialize ObjectAttributes for the window station object */ - InitializeObjectAttributes( - &ObjectAttributes, - &FullWindowStationName, - 0, - NULL, - NULL); - Status = ObOpenObjectByName( - &ObjectAttributes, + ObjectAttributes, ExWindowStationObjectType, - KernelMode, + UserMode, NULL, dwDesiredAccess, NULL, @@ -454,24 +416,39 @@ NtUserCreateWindowStation( if (NT_SUCCESS(Status)) { - DPRINT("Successfully opened window station (%wZ)\n", - FullWindowStationName); - ExFreePool(FullWindowStationName.Buffer); - ReleaseCapturedUnicodeString(&WindowStationName, UserMode); return (HWINSTA)WindowStation; } + /* * No existing window station found, try to create new one */ + + /* Capture window station name */ + _SEH2_TRY + { + ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1); + Status = IntSafeCopyUnicodeString(&WindowStationName, ObjectAttributes->ObjectName); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status =_SEH2_GetExceptionCode(); + } + _SEH2_END - DPRINT("Creating window station (%wZ)\n", &FullWindowStationName); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed reading capturing window station name\n"); + SetLastNtError(Status); + return NULL; + } + /* Create the window station object */ Status = ObCreateObject( - KernelMode, + UserMode, ExWindowStationObjectType, - &ObjectAttributes, - ExGetPreviousMode(), + ObjectAttributes, + UserMode, NULL, sizeof(WINSTATION_OBJECT), 0, @@ -480,26 +457,11 @@ NtUserCreateWindowStation( if (!NT_SUCCESS(Status)) { - DPRINT1("Failed creating window station (%wZ)\n", &FullWindowStationName); - ExFreePool(FullWindowStationName.Buffer); - ReleaseCapturedUnicodeString(&WindowStationName, UserMode); + ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); return 0; } - /* Zero out the buffer */ - RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT)); - - KeInitializeSpinLock(&WindowStationObject->Lock); - - InitializeListHead(&WindowStationObject->DesktopListHead); - - WindowStationObject->AtomTable = NULL; - Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable); - WindowStationObject->SystemMenuTemplate = (HANDLE)0; - - WindowStationObject->Name = WindowStationName; - Status = ObInsertObject( (PVOID)WindowStationObject, NULL, @@ -510,20 +472,21 @@ NtUserCreateWindowStation( if (!NT_SUCCESS(Status)) { - DPRINT1("Failed creating window station (%wZ)\n", &FullWindowStationName); - ExFreePool(FullWindowStationName.Buffer); - ExFreePool(WindowStationName.Buffer); + ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); ObDereferenceObject(WindowStationObject); return 0; } - /* - * Initialize the new window station object - */ + /* Initialize the window station */ + RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT)); + KeInitializeSpinLock(&WindowStationObject->Lock); + InitializeListHead(&WindowStationObject->DesktopListHead); + Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable); + WindowStationObject->SystemMenuTemplate = (HANDLE)0; + WindowStationObject->Name = WindowStationName; WindowStationObject->ScreenSaverRunning = FALSE; - WindowStationObject->FlatMenu = FALSE; if (!IntSetupClipboard(WindowStationObject)) @@ -538,8 +501,6 @@ NtUserCreateWindowStation( InitCursorImpl(); } - DPRINT("Window station successfully created (%wZ)\n", &FullWindowStationName); - ExFreePool(FullWindowStationName.Buffer); return WindowStation; } @@ -569,39 +530,16 @@ NtUserCreateWindowStation( HWINSTA APIENTRY NtUserOpenWindowStation( - PUNICODE_STRING lpszWindowStationName, + POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess) { - UNICODE_STRING WindowStationName; HWINSTA WindowStation; - OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; - /* - * Generate full window station name - */ - - if (!IntGetFullWindowStationName(&WindowStationName, lpszWindowStationName, - NULL)) - { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return 0; - } - - DPRINT("Trying to open window station (%wZ)\n", &WindowStationName); - - /* Initialize ObjectAttributes for the window station object */ - InitializeObjectAttributes( - &ObjectAttributes, - &WindowStationName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = ObOpenObjectByName( - &ObjectAttributes, + ObjectAttributes, ExWindowStationObjectType, - KernelMode, + UserMode, NULL, dwDesiredAccess, NULL, @@ -610,13 +548,9 @@ NtUserOpenWindowStation( if (!NT_SUCCESS(Status)) { SetLastNtError(Status); - ExFreePool(WindowStationName.Buffer); return 0; } - DPRINT("Successfully opened window station (%wZ)\n", &WindowStationName); - ExFreePool(WindowStationName.Buffer); - return WindowStation; } From 6fc1e4e1225c3da3bc2e48dd21c617815508f16f Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 17 Mar 2011 14:24:34 +0000 Subject: [PATCH 21/90] [RTL] - Limit unimplemented warnings about RtlActivateActivationContextUnsafeFast calls for now so that they don't flood the log too much. svn path=/trunk/; revision=51083 --- reactos/lib/rtl/actctx.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/reactos/lib/rtl/actctx.c b/reactos/lib/rtl/actctx.c index a91e1e8a7b1..cd900e1b8de 100644 --- a/reactos/lib/rtl/actctx.c +++ b/reactos/lib/rtl/actctx.c @@ -2735,7 +2735,12 @@ NTAPI RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context) { - UNIMPLEMENTED; + static int i; + + if (i == 0) + UNIMPLEMENTED; + i++; + return STATUS_NOT_IMPLEMENTED; } @@ -2743,7 +2748,12 @@ NTSTATUS NTAPI RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame) { - UNIMPLEMENTED; + static int i; + + if (i == 0) + UNIMPLEMENTED; + i++; + return STATUS_NOT_IMPLEMENTED; } From 3b6432c7ed31986d0e994f827c6d44ae9ec1cc9d Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 17 Mar 2011 14:25:59 +0000 Subject: [PATCH 22/90] [NTDLL] - Implement fetching address of a security cookie in an image. Still not used even if it's present there. - Silence some debug prints. svn path=/trunk/; revision=51084 --- reactos/dll/ntdll/ldr/ldrinit.c | 70 ++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index e832276657e..2440d4c6d5d 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -343,6 +343,62 @@ LdrpEnsureLoaderLockIsHeld() // Ignored atm } +PVOID +NTAPI +LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage) +{ + PIMAGE_LOAD_CONFIG_DIRECTORY ConfigDir; + ULONG DirSize; + PVOID Cookie = NULL; + + /* Check NT header first */ + if (!RtlImageNtHeader(BaseAddress)) return NULL; + + /* Get the pointer to the config directory */ + ConfigDir = RtlImageDirectoryEntryToData(BaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, + &DirSize); + + /* Check for sanity */ + if (!ConfigDir || + (DirSize != 64 && ConfigDir->Size != DirSize) || + (ConfigDir->Size < 0x48)) + return NULL; + + /* Now get the cookie */ + Cookie = (PVOID)ConfigDir->SecurityCookie; + + /* Check this cookie */ + if (Cookie == NULL || + (PCHAR)Cookie <= (PCHAR)BaseAddress || + (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage) + { + Cookie = NULL; + } + + /* Return validated security cookie */ + return Cookie; +} + +PVOID +NTAPI +LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry) +{ + PVOID Cookie; + + /* Fetch address of the cookie */ + Cookie = LdrpFetchAddressOfSecurityCookie(LdrEntry->DllBase, LdrEntry->SizeOfImage); + + if (Cookie) + { + UNIMPLEMENTED; + Cookie = NULL; + } + + return Cookie; +} + NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) @@ -361,7 +417,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) PTEB OldTldTeb; BOOLEAN DllStatus; - DPRINT1("LdrpRunInitializeRoutines() called for %wZ\n", &LdrpImageEntry->BaseDllName); + DPRINT("LdrpRunInitializeRoutines() called for %wZ\n", &LdrpImageEntry->BaseDllName); /* Check the Loader Lock */ LdrpEnsureLoaderLockIsHeld(); @@ -417,8 +473,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED)) { /* Setup the Cookie for the DLL */ - //LdrpInitSecurityCookie(LdrEntry); - UNIMPLEMENTED; + LdrpInitSecurityCookie(LdrEntry); /* Check for valid entrypoint */ if (LdrEntry->EntryPoint) @@ -474,7 +529,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) /* Get an entry */ LdrEntry = LdrRootEntry[i]; - /* FIXME: Verifiy NX Compat */ + /* FIXME: Verify NX Compat */ /* Move to next entry */ i++; @@ -534,8 +589,11 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) } /* Call the Entrypoint */ - DPRINT1("%wZ - Calling entry point at %x for thread attaching\n", - &LdrEntry->BaseDllName, EntryPoint); + if (ShowSnaps) + { + DPRINT1("%wZ - Calling entry point at %p for DLL_PROCESS_ATTACH\n", + &LdrEntry->BaseDllName, EntryPoint); + } DllStatus = LdrpCallDllEntry(EntryPoint, LdrEntry->DllBase, DLL_PROCESS_ATTACH, From 1ba1132e21075ec91011664120715a74a30b2445 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 17 Mar 2011 17:47:42 +0000 Subject: [PATCH 23/90] [NTDLL/LDR] - Use LdrpRunInitializeRoutines() instead of the old LdrpAttachThread(). This adds calls to unimplemented context functions, but since they were not called at all by the old code it shouldn't change the behaviour significantly. Besides of that, it's start of significant changes in the "mainstream" codepaths, so regressions might occur. svn path=/trunk/; revision=51085 --- reactos/dll/ntdll/ldr/utils.c | 82 +---------------------------------- 1 file changed, 2 insertions(+), 80 deletions(-) diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 7ed646ff494..77a18cc17cd 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -47,7 +47,6 @@ static NTSTATUS LdrpLoadModule(IN PWSTR SearchPath OPTIONAL, IN PUNICODE_STRING Name, OUT PLDR_DATA_TABLE_ENTRY *Module, OUT PVOID *BaseAddress OPTIONAL); -static NTSTATUS LdrpAttachProcess(VOID); static VOID LdrpDetachProcess(BOOLEAN UnloadAll); static NTSTATUS LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module, BOOLEAN Unload); @@ -745,7 +744,7 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, if (!(Module->Flags & LDRP_PROCESS_ATTACH_CALLED)) { RtlEnterCriticalSection(Peb->LoaderLock); - Status = LdrpAttachProcess(); + Status = LdrpRunInitializeRoutines(NULL); RtlLeaveCriticalSection(Peb->LoaderLock); } if (Module->EntryPointActivationContext) RtlDeactivateActivationContext(0, cookie); @@ -2036,7 +2035,7 @@ PEPFUNC LdrPEStartup (PVOID ImageBase, Status = LdrpInitializeTls(); if (NT_SUCCESS(Status)) { - Status = LdrpAttachProcess(); + Status = LdrpRunInitializeRoutines(NULL); } if (NT_SUCCESS(Status)) { @@ -2643,83 +2642,6 @@ LdrpDetachProcess(BOOLEAN UnloadAll) DPRINT("LdrpDetachProcess() done\n"); } -/********************************************************************** - * NAME LOCAL - * LdrpAttachProcess - * - * DESCRIPTION - * Initialize all dll's which are prepered for loading - * - * ARGUMENTS - * none - * - * RETURN VALUE - * status - * - * REVISIONS - * - * NOTE - * The loader lock must be held on entry. - * - */ -static NTSTATUS -LdrpAttachProcess(VOID) -{ - PLIST_ENTRY ModuleListHead; - PLIST_ENTRY Entry; - PLDR_DATA_TABLE_ENTRY Module; - BOOLEAN Result; - NTSTATUS Status = STATUS_SUCCESS; - - DPRINT("LdrpAttachProcess() called for %wZ\n", - &LdrpImageEntry->BaseDllName); - - ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList; - Entry = ModuleListHead->Flink; - while (Entry != ModuleListHead) - { - Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); - if (!(Module->Flags & (LDRP_LOAD_IN_PROGRESS|LDRP_UNLOAD_IN_PROGRESS|LDRP_ENTRY_PROCESSED))) - { - Module->Flags |= LDRP_LOAD_IN_PROGRESS; - TRACE_LDR("%wZ loaded - Calling init routine at %x for process attaching\n", - &Module->BaseDllName, Module->EntryPoint); - - /* Check if it has TLS */ - if (Module->TlsIndex && FALSE/*Context*/) - { - /* Call TLS */ - LdrpTlsCallback(Module->DllBase, DLL_PROCESS_ATTACH); - } - - if ((Module->Flags & LDRP_IMAGE_DLL) && Module->EntryPoint) - Result = LdrpCallDllEntry(Module->EntryPoint, Module->DllBase, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0)); - else - Result = TRUE; - - if (!Result) - { - Status = STATUS_DLL_INIT_FAILED; - break; - } - if (Module->Flags & LDRP_IMAGE_DLL && Module->EntryPoint != 0) - { - Module->Flags |= LDRP_PROCESS_ATTACH_CALLED|LDRP_ENTRY_PROCESSED; - } - else - { - Module->Flags |= LDRP_ENTRY_PROCESSED; - } - Module->Flags &= ~LDRP_LOAD_IN_PROGRESS; - } - Entry = Entry->Flink; - } - - DPRINT("LdrpAttachProcess() done\n"); - - return Status; -} - /* * @implemented */ From b75783bd61df770138c5e08a03b4c5d8a83c8e2c Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Thu, 17 Mar 2011 20:32:24 +0000 Subject: [PATCH 24/90] [win32k] - SetThreadDesktop: Actually set hdesk in PTHREADINFO Now GetThreadDesktop doesn't return 0 svn path=/trunk/; revision=51086 --- .../subsystems/win32/win32k/include/desktop.h | 2 +- .../subsystems/win32/win32k/main/dllmain.c | 19 +- .../subsystems/win32/win32k/ntuser/desktop.c | 221 +++++++++--------- 3 files changed, 114 insertions(+), 128 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/desktop.h b/reactos/subsystems/win32/win32k/include/desktop.h index 12911139223..388a0f4c23c 100644 --- a/reactos/subsystems/win32/win32k/include/desktop.h +++ b/reactos/subsystems/win32/win32k/include/desktop.h @@ -102,7 +102,7 @@ IntHideDesktop(PDESKTOP Desktop); HDESK FASTCALL IntGetDesktopObjectHandle(PDESKTOP DesktopObject); -BOOL IntSetThreadDesktop(IN PDESKTOP DesktopObject, +BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure); NTSTATUS FASTCALL diff --git a/reactos/subsystems/win32/win32k/main/dllmain.c b/reactos/subsystems/win32/win32k/main/dllmain.c index f78bf1940b9..a9202233735 100644 --- a/reactos/subsystems/win32/win32k/main/dllmain.c +++ b/reactos/subsystems/win32/win32k/main/dllmain.c @@ -237,26 +237,11 @@ Win32kThreadCallback(struct _ETHREAD *Thread, if (hDesk != NULL) { - PDESKTOP DesktopObject; Win32Thread->rpdesk = NULL; - Status = ObReferenceObjectByHandle(hDesk, - 0, - ExDesktopObjectType, - KernelMode, - (PVOID*)&DesktopObject, - NULL); - NtClose(hDesk); - if(NT_SUCCESS(Status)) + Win32Thread->hdesk = NULL; + if (!IntSetThreadDesktop(hDesk, FALSE)) { - if (!IntSetThreadDesktop(DesktopObject, - FALSE)) - { DPRINT1("Unable to set thread desktop\n"); - } - } - else - { - DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk); } } } diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index c2d1c29f7bb..f56d587f648 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -1055,7 +1055,7 @@ NtUserCreateDesktop( } #endif - if (!ptiCurrent->rpdesk) IntSetThreadDesktop(DesktopObject,FALSE); + if (!ptiCurrent->rpdesk) IntSetThreadDesktop(Desktop,FALSE); /* Based on wine/server/window.c in get_desktop_window. @@ -1795,105 +1795,131 @@ IntMapDesktopView(IN PDESKTOP DesktopObject) } BOOL -IntSetThreadDesktop(IN PDESKTOP DesktopObject, +IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure) { - PDESKTOP OldDesktop; + PDESKTOP DesktopObject, OldDesktop; + HDESK hOldDesktop; PTHREADINFO W32Thread; NTSTATUS Status; BOOL MapHeap; CLIENTTHREADINFO ctiSave; - DPRINT("IntSetThreadDesktop() DO=%p, FOF=%d\n", DesktopObject, FreeOnFailure); + DPRINT("IntSetThreadDesktop() , FOF=%d\n", FreeOnFailure); MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess); W32Thread = PsGetCurrentThreadWin32Thread(); + + /* Validate the new desktop. */ + Status = IntValidateDesktopHandle( + hDesktop, + UserMode, + 0, + &DesktopObject); - if (W32Thread->rpdesk != DesktopObject) + if (!NT_SUCCESS(Status)) { - OldDesktop = W32Thread->rpdesk; + DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); + return FALSE; + } - if (!IsListEmpty(&W32Thread->WindowListHead)) + if (W32Thread->rpdesk == DesktopObject) + { + /* Nothing to do */ + ObDereferenceObject(DesktopObject); + return TRUE; + } + + if (!IsListEmpty(&W32Thread->WindowListHead)) + { + DPRINT1("Attempted to change thread desktop although the thread has windows!\n"); + EngSetLastError(ERROR_BUSY); + return FALSE; + } + + OldDesktop = W32Thread->rpdesk; + hOldDesktop = W32Thread->hdesk; + + W32Thread->rpdesk = DesktopObject; + W32Thread->hdesk = hDesktop; + + if (MapHeap && DesktopObject != NULL) + { + Status = IntMapDesktopView(DesktopObject); + if (!NT_SUCCESS(Status)) { - DPRINT1("Attempted to change thread desktop although the thread has windows!\n"); - EngSetLastError(ERROR_BUSY); + SetLastNtError(Status); return FALSE; } + W32Thread->pDeskInfo = DesktopObject->pDeskInfo; + } - W32Thread->rpdesk = DesktopObject; + RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO)); + if (W32Thread->pcti && OldDesktop && NtCurrentTeb()) + { + RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO)); + DPRINT("Free ClientThreadInfo\n"); + DesktopHeapFree(OldDesktop, W32Thread->pcti); + W32Thread->pcti = NULL; + } + + if (!W32Thread->pcti && DesktopObject && NtCurrentTeb()) + { + DPRINT("Allocate ClientThreadInfo\n"); + W32Thread->pcti = DesktopHeapAlloc( DesktopObject, + sizeof(CLIENTTHREADINFO)); + RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO)); + } + + if (NtCurrentTeb()) + { + PCLIENTINFO pci = GetWin32ClientInfo(); + pci->ulClientDelta = DesktopHeapGetUserDelta(); + if (DesktopObject) + { + pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta); + if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta); + } + } + + if (OldDesktop != NULL && + !IntCheckProcessDesktopClasses(OldDesktop, + FreeOnFailure)) + { + DPRINT1("Failed to move process classes to shared heap!\n"); + + /* failed to move desktop classes to the shared heap, + unmap the view and return the error */ if (MapHeap && DesktopObject != NULL) + IntUnmapDesktopView(DesktopObject); + + return FALSE; + } + + /* Remove the thread from the old desktop's list */ + RemoveEntryList(&W32Thread->PtiLink); + + if (DesktopObject != NULL) + { + ObReferenceObject(DesktopObject); + /* Insert into new desktop's list */ + InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink); + } + + /* Close the old desktop */ + if (OldDesktop != NULL) + { + if (MapHeap) { - Status = IntMapDesktopView(DesktopObject); - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return FALSE; - } - W32Thread->pDeskInfo = DesktopObject->pDeskInfo; + IntUnmapDesktopView(OldDesktop); } - RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO)); - - if (W32Thread->pcti && OldDesktop && NtCurrentTeb()) - { - RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO)); - DPRINT("Free ClientThreadInfo\n"); - DesktopHeapFree(OldDesktop, W32Thread->pcti); - W32Thread->pcti = NULL; - } - - if (!W32Thread->pcti && DesktopObject && NtCurrentTeb()) - { - DPRINT("Allocate ClientThreadInfo\n"); - W32Thread->pcti = DesktopHeapAlloc( DesktopObject, - sizeof(CLIENTTHREADINFO)); - RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO)); - } - - if (NtCurrentTeb()) - { - PCLIENTINFO pci = GetWin32ClientInfo(); - pci->ulClientDelta = DesktopHeapGetUserDelta(); - if (DesktopObject) - { - pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta); - if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta); - } - } - - if (OldDesktop != NULL && - !IntCheckProcessDesktopClasses(OldDesktop, - FreeOnFailure)) - { - DPRINT1("Failed to move process classes to shared heap!\n"); - - /* failed to move desktop classes to the shared heap, - unmap the view and return the error */ - if (MapHeap && DesktopObject != NULL) - IntUnmapDesktopView(DesktopObject); - - return FALSE; - } - - /* Remove the thread from the old desktop's list */ - RemoveEntryList(&W32Thread->PtiLink); - - if (DesktopObject != NULL) - { - ObReferenceObject(DesktopObject); - /* Insert into new desktop's list */ - InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink); - } - - if (OldDesktop != NULL) - { - if (MapHeap) - { - IntUnmapDesktopView(OldDesktop); - } - - ObDereferenceObject(OldDesktop); - } + ObDereferenceObject(OldDesktop); + } + + if (hOldDesktop != NULL) + { + ZwClose(hOldDesktop); } return TRUE; @@ -1909,40 +1935,15 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject, BOOL APIENTRY NtUserSetThreadDesktop(HDESK hDesktop) { - PDESKTOP DesktopObject; - NTSTATUS Status; - DECLARE_RETURN(BOOL); + BOOL ret; UserEnterExclusive(); - DPRINT("Enter NtUserSetThreadDesktop\n"); - - /* Validate the new desktop. */ - Status = IntValidateDesktopHandle( - hDesktop, - UserMode, - 0, - &DesktopObject); - - if (!NT_SUCCESS(Status)) - { - DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); - RETURN(FALSE); - } - - /* FIXME: Should check here to see if the thread has any windows. */ - - if (!IntSetThreadDesktop(DesktopObject, - FALSE)) - { - RETURN(FALSE); - } - - RETURN(TRUE); - -CLEANUP: - DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_); + + ret = IntSetThreadDesktop(hDesktop, FALSE); + UserLeave(); - END_CLEANUP; + + return ret; } /* EOF */ From 39b14c177e0560e09c12e2343aad267a67831768 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 18 Mar 2011 16:28:21 +0000 Subject: [PATCH 25/90] [Y] - Fix argument checking - Close correct handle - Patch by Kuts Alexey - bug 6004 svn path=/trunk/; revision=51087 --- rosapps/applications/cmdutils/y/y.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rosapps/applications/cmdutils/y/y.c b/rosapps/applications/cmdutils/y/y.c index c048d85f067..1e052bdbb51 100644 --- a/rosapps/applications/cmdutils/y/y.c +++ b/rosapps/applications/cmdutils/y/y.c @@ -53,7 +53,7 @@ int main (int argc, char **argv) hConsoleIn = GetStdHandle(STD_INPUT_HANDLE); hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE); - if (_tcsncmp (argv[1], _T("/?"), 2) == 0) + if (argc == 2 && _tcsncmp (argv[1], _T("/?"), 2) == 0) { ConOutPuts(_T("copy stdin to stdout and then files to stdout\n" "\n" @@ -115,7 +115,7 @@ int main (int argc, char **argv) } while(FindNextFile(hFind,&FindData)); - FindClose(hFile); + FindClose(hFind); } return 0; From f5912e7155e3f696e6aa0cf597882783cc522d29 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 18 Mar 2011 20:23:18 +0000 Subject: [PATCH 26/90] [NTDLL] - Rewrite the very first initialization routine: LdrpInit(). - Rename LdrpInit2() to LdrpInitializeProcess(), and LdrpAttachThread() to LdrpInitializeThread(). Still old code there. svn path=/trunk/; revision=51088 --- reactos/dll/ntdll/include/ntdllp.h | 3 + reactos/dll/ntdll/ldr/ldrinit.c | 149 +++++++++++++++++++++++++++++ reactos/dll/ntdll/ldr/startup.c | 51 +--------- reactos/dll/ntdll/ldr/utils.c | 4 +- 4 files changed, 159 insertions(+), 48 deletions(-) diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index c882ef0e263..fcb04a98a6e 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -27,11 +27,14 @@ extern BOOLEAN LdrpInLdrInit; /* ldrinit.c */ NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL); +NTSTATUS NTAPI LdrpInitializeThread(IN PCONTEXT Context); NTSTATUS NTAPI LdrpInitializeTls(VOID); NTSTATUS NTAPI LdrpAllocateTls(VOID); VOID NTAPI LdrpFreeTls(VOID); VOID NTAPI LdrpTlsCallback(PVOID BaseAddress, ULONG Reason); BOOLEAN NTAPI LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint, PVOID BaseAddress, ULONG Reason, PVOID Context); +NTSTATUS NTAPI LdrpInitializeProcess(PCONTEXT Context, PVOID SystemArgument1); + /* ldrpe.c */ NTSTATUS diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index 2440d4c6d5d..535bce90b8c 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -21,6 +21,7 @@ UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machin UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); BOOLEAN LdrpInLdrInit; +LONG LdrpProcessInitialized; PLDR_DATA_TABLE_ENTRY LdrpImageEntry; PUNICODE_STRING LdrpTopLevelDllBeingLoaded; @@ -39,6 +40,11 @@ RTL_CRITICAL_SECTION LdrpLoaderLock; BOOLEAN ShowSnaps; +ULONG LdrpFatalHardErrorCount; + +VOID RtlpInitializeVectoredExceptionHandling(VOID); +VOID NTAPI RtlpInitDeferedCriticalSection(VOID); + /* FUNCTIONS *****************************************************************/ /* @@ -832,5 +838,148 @@ LdrpFreeTls(VOID) TlsVector); } +VOID +NTAPI +LdrpInitFailure(NTSTATUS Status) +{ + ULONG Response; + + /* Print a debug message */ + DPRINT1("LDR: Process initialization failure; NTSTATUS = %08lx\n", Status); + + /* Raise a hard error */ + if (!LdrpFatalHardErrorCount) + { + ZwRaiseHardError(STATUS_APP_INIT_FAILURE, 1, 0, (PULONG_PTR)&Status, OptionOk, &Response); + } +} + +VOID +NTAPI +LdrpInit(PCONTEXT Context, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + LARGE_INTEGER Timeout; + PTEB Teb = NtCurrentTeb(); + NTSTATUS Status, LoaderStatus = STATUS_SUCCESS; + MEMORY_BASIC_INFORMATION MemoryBasicInfo; + PPEB Peb = NtCurrentPeb(); + + DPRINT("LdrpInit()\n"); + + /* Check if we have a deallocation stack */ + if (!Teb->DeallocationStack) + { + /* We don't, set one */ + Status = NtQueryVirtualMemory(NtCurrentProcess(), + Teb->NtTib.StackLimit, + MemoryBasicInformation, + &MemoryBasicInfo, + sizeof(MEMORY_BASIC_INFORMATION), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + LdrpInitFailure(Status); + RtlRaiseStatus(Status); + return; + } + + /* Set the stack */ + Teb->DeallocationStack = MemoryBasicInfo.AllocationBase; + } + + /* Now check if the process is already being initialized */ + while (_InterlockedCompareExchange(&LdrpProcessInitialized, + 1, + 0) == 1) + { + /* Set the timeout to 30 seconds */ + Timeout.QuadPart = Int32x32To64(30, -10000); + + /* Make sure the status hasn't changed */ + while (!LdrpProcessInitialized) + { + /* Do the wait */ + ZwDelayExecution(FALSE, &Timeout); + } + } + + /* Check if we have already setup LDR data */ + if (!Peb->Ldr) + { + /* Setup the Loader Lock */ + Peb->LoaderLock = &LdrpLoaderLock; + + /* Let other code know we're initializing */ + LdrpInLdrInit = TRUE; + + /* Initialize Critical Section Data */ + RtlpInitDeferedCriticalSection(); + + /* Initialize VEH Call lists */ + RtlpInitializeVectoredExceptionHandling(); + + /* Protect with SEH */ + _SEH2_TRY + { + /* Initialize the Process */ + LoaderStatus = LdrpInitializeProcess(Context, + SystemArgument1); + + /* Check for success and if MinimumStackCommit was requested */ + if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit) + { + /* Enforce the limit */ + //LdrpTouchThreadStack(Peb->MinimumStackCommit); + UNIMPLEMENTED; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + LoaderStatus = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* We're not initializing anymore */ + LdrpInLdrInit = FALSE; + + /* Check if init worked */ + if (NT_SUCCESS(LoaderStatus)) + { + /* Set the process as Initialized */ + _InterlockedIncrement(&LdrpProcessInitialized); + } + } + else + { + /* Loader data is there... is this a fork() ? */ + if(Peb->InheritedAddressSpace) + { + /* Handle the fork() */ + //LoaderStatus = LdrpForkProcess(); + LoaderStatus = STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + } + else + { + /* This is a new thread initializing */ + LdrpInitializeThread(Context); + } + } + + /* All done, test alert the thread */ + NtTestAlert(); + + /* Return */ + if (!NT_SUCCESS(LoaderStatus)) + { + /* Fail */ + LdrpInitFailure(LoaderStatus); + RtlRaiseStatus(LoaderStatus); + } +} /* EOF */ diff --git a/reactos/dll/ntdll/ldr/startup.c b/reactos/dll/ntdll/ldr/startup.c index 774f4495d50..731842ac26e 100644 --- a/reactos/dll/ntdll/ldr/startup.c +++ b/reactos/dll/ntdll/ldr/startup.c @@ -16,9 +16,6 @@ VOID RtlInitializeHeapManager(VOID); VOID LdrpInitLoader(VOID); -VOID NTAPI RtlpInitDeferedCriticalSection(VOID); -NTSTATUS LdrpAttachThread(VOID); -VOID RtlpInitializeVectoredExceptionHandling(VOID); extern PTEB LdrpTopLevelDllBeingLoadedTeb; /* GLOBALS *******************************************************************/ @@ -27,8 +24,6 @@ extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry; static RTL_CRITICAL_SECTION PebLock; static RTL_BITMAP TlsBitMap; static RTL_BITMAP TlsExpansionBitMap; -static volatile BOOLEAN LdrpInitialized = FALSE; -static LONG LdrpInitLock = 0; #define VALUE_BUFFER_SIZE 256 @@ -312,11 +307,10 @@ finish: return FALSE; } -static -VOID -LdrpInit2(PCONTEXT Context, - PVOID SystemArgument1, - PVOID SystemArgument2) +NTSTATUS +NTAPI +LdrpInitializeProcess(PCONTEXT Context, + PVOID SystemArgument1) { PIMAGE_NT_HEADERS NTHeaders; PEPFUNC EntryPoint; @@ -378,9 +372,6 @@ LdrpInit2(PCONTEXT Context, Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors; - /* Initialize Critical Section Data */ - RtlpInitDeferedCriticalSection(); - /* Load execution options */ LoadImageFileExecutionOptions(Peb); @@ -439,9 +430,6 @@ LdrpInit2(PCONTEXT Context, ZwTerminateProcess(NtCurrentProcess(), STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE); } - /* initialized vectored exception handling */ - RtlpInitializeVectoredExceptionHandling(); - /* initalize peb lock support */ RtlInitializeCriticalSection(&PebLock); Peb->FastPebLock = &PebLock; @@ -585,37 +573,8 @@ LdrpInit2(PCONTEXT Context, /* Break into debugger */ if (Peb->BeingDebugged) DbgBreakPoint(); -} -VOID -NTAPI -LdrpInit(PCONTEXT Context, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - if (!LdrpInitialized) - { - if (!_InterlockedExchange(&LdrpInitLock, 1)) - { - LdrpInit2(Context, SystemArgument1, SystemArgument2); - LdrpInitialized = TRUE; - } - else - { - LARGE_INTEGER Interval = {{-200000, -1}}; - - do - { - NtDelayExecution(FALSE, &Interval); - } - while (!LdrpInitialized); - } - } - - /* attach the thread */ - RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); - LdrpAttachThread(); - RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); + return STATUS_SUCCESS; } /* EOF */ diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 77a18cc17cd..2f660dacdbe 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -2664,9 +2664,9 @@ LdrShutdownProcess (VOID) /* * @implemented */ - NTSTATUS -LdrpAttachThread (VOID) +NTAPI +LdrpInitializeThread(IN PCONTEXT Context) { PLIST_ENTRY ModuleListHead; PLIST_ENTRY Entry; From 115d07d6866a440f62995f6f9376abcaafae04cb Mon Sep 17 00:00:00 2001 From: James Tabor Date: Fri, 18 Mar 2011 22:41:22 +0000 Subject: [PATCH 27/90] [Win32k] - Implement the set of DeferWindowPos functions. Regedit (one of many application) uses it and allocated three when it should be four. This was a good test to verify the batch list growing routine. Instead of drawing per DeferWindowPos call, now a real list is created and run down as a batch. - ReactOS should handle this the correct way and a good test case is located here: http://bugs.winehq.org/show_bug.cgi?id=23187 - The code is from wine and modified for the use in ReactOS. svn path=/trunk/; revision=51089 --- reactos/dll/win32/user32/windows/window.c | 24 +-- reactos/include/reactos/win32k/ntuser.h | 4 +- .../subsystems/win32/win32k/include/winpos.h | 29 +++ .../subsystems/win32/win32k/ntuser/ntstubs.c | 33 +-- .../subsystems/win32/win32k/ntuser/object.c | 1 + .../win32/win32k/ntuser/simplecall.c | 32 +++ .../subsystems/win32/win32k/ntuser/winpos.c | 198 ++++++++++++++++++ 7 files changed, 265 insertions(+), 56 deletions(-) diff --git a/reactos/dll/win32/user32/windows/window.c b/reactos/dll/win32/user32/windows/window.c index 2025d815617..4cc757fcf5f 100644 --- a/reactos/dll/win32/user32/windows/window.c +++ b/reactos/dll/win32/user32/windows/window.c @@ -65,17 +65,7 @@ AllowSetForegroundWindow(DWORD dwProcessId) HDWP WINAPI BeginDeferWindowPos(int nNumWindows) { - if (nNumWindows < 0) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } -#if 0 - UNIMPLEMENTED; - return (HDWP)0; -#else - return (HDWP)1; -#endif + return (HDWP)NtUserCallOneParam((DWORD_PTR)nNumWindows, ONEPARAM_ROUTINE_BEGINDEFERWNDPOS); } @@ -567,12 +557,7 @@ DeferWindowPos(HDWP hWinPosInfo, int cy, UINT uFlags) { -#if 0 return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags); -#else - SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags); - return hWinPosInfo; -#endif } @@ -582,12 +567,7 @@ DeferWindowPos(HDWP hWinPosInfo, BOOL WINAPI EndDeferWindowPos(HDWP hWinPosInfo) { -#if 0 - UNIMPLEMENTED; - return FALSE; -#else - return TRUE; -#endif + return NtUserEndDeferWindowPosEx(hWinPosInfo, 0); } diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index d9f28d6fa0e..484a3a4b84c 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -1631,10 +1631,10 @@ NtUserEnableScrollBar( UINT wSBflags, UINT wArrows); -DWORD +BOOL NTAPI NtUserEndDeferWindowPosEx( - DWORD Unknown0, + HDWP WinPosInfo, DWORD Unknown1); BOOL NTAPI diff --git a/reactos/subsystems/win32/win32k/include/winpos.h b/reactos/subsystems/win32/win32k/include/winpos.h index 7f1c52a4124..a230972ab5a 100644 --- a/reactos/subsystems/win32/win32k/include/winpos.h +++ b/reactos/subsystems/win32/win32k/include/winpos.h @@ -1,5 +1,32 @@ #pragma once +typedef struct _CVR // Tag Ussw +{ + WINDOWPOS pos; + LONG xClientNew; + LONG yClientNew; + LONG cxClientNew; + LONG cyClientNew; + RECT rcBlt; + LONG dxBlt; + LONG dyBlt; + UINT fsRE; + HRGN hrgnVisOld; + PTHREADINFO pti; + HRGN hrgnClip; + HRGN hrgnInterMonitor; +} CVR, *PCVR; + +typedef struct _SMWP +{ + HEAD head; + UINT bShellNotify:1; + UINT bHandle:1; + INT ccvr; + INT ccvrAlloc; + PCVR acvr; +} SMWP, *PSMWP; + #define IntPtInWindow(WndObject,x,y) \ ((x) >= (WndObject)->rcWindow.left && \ (x) < (WndObject)->rcWindow.right && \ @@ -36,3 +63,5 @@ VOID FASTCALL co_WinPosActivateOtherWindow(PWND Window); VOID FASTCALL WinPosInitInternalPos(PWND WindowObject, POINT *pt, RECTL *RestoreRect); +BOOL FASTCALL IntEndDeferWindowPosEx(HDWP); +HDWP FASTCALL IntDeferWindowPos(HDWP,HWND,HWND,INT,INT,INT,INT,UINT); diff --git a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c index 7d405821102..774ee67e84b 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c @@ -1168,18 +1168,6 @@ NtUserDrawMenuBarTemp( return 0; } -/* - * @unimplemented - */ -DWORD APIENTRY -NtUserEndDeferWindowPosEx(DWORD Unknown0, - DWORD Unknown1) -{ - UNIMPLEMENTED - - return 0; -} - /* * FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND. */ @@ -1205,7 +1193,7 @@ NtUserFlashWindowEx(IN PFLASHWINFO pfwi) { UNIMPLEMENTED - return 0; + return 1; } /* @@ -1305,25 +1293,6 @@ NtUserWindowFromPhysicalPoint(POINT Point) return NULL; } -/* - * @unimplemented - */ -HDWP APIENTRY -NtUserDeferWindowPos(HDWP WinPosInfo, - HWND Wnd, - HWND WndInsertAfter, - int x, - int y, - int cx, - int cy, - UINT Flags) -{ - UNIMPLEMENTED - - return 0; -} - - /* * NtUserResolveDesktopForWOW * diff --git a/reactos/subsystems/win32/win32k/ntuser/object.c b/reactos/subsystems/win32/win32k/ntuser/object.c index 8376f0bfd84..4df5c8f8f6d 100644 --- a/reactos/subsystems/win32/win32k/ntuser/object.c +++ b/reactos/subsystems/win32/win32k/ntuser/object.c @@ -177,6 +177,7 @@ UserHandleOwnerByType(USER_OBJECT_TYPE type) case otHook: case otCallProc: case otAccel: + case otSMWP: pi = GetW32ProcessInfo(); break; diff --git a/reactos/subsystems/win32/win32k/ntuser/simplecall.c b/reactos/subsystems/win32/win32k/ntuser/simplecall.c index 2c4844f0e98..1e74111f4f5 100644 --- a/reactos/subsystems/win32/win32k/ntuser/simplecall.c +++ b/reactos/subsystems/win32/win32k/ntuser/simplecall.c @@ -157,6 +157,38 @@ NtUserCallOneParam( MsqPostQuitMessage(pti->MessageQueue, Param); RETURN(TRUE); } + + case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS: + { + PSMWP psmwp; + HDWP hDwp = NULL; + if (Param < 0) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + RETURN(0); + } + /* Windows allows zero count, in which case it allocates context for 8 moves */ + if (Param == 0) Param = 8; + + psmwp = (PSMWP) UserCreateObject( gHandleTable, + NULL, + (PHANDLE)&hDwp, + otSMWP, + sizeof(SMWP)); + if (!psmwp) RETURN(0); + psmwp->acvr = ExAllocatePoolWithTag(PagedPool, Param * sizeof(CVR), USERTAG_SWP); + if (!psmwp->acvr) + { + UserDeleteObject(hDwp, otSMWP); + RETURN(0); + } + RtlZeroMemory(psmwp->acvr, Param * sizeof(CVR)); + psmwp->bHandle = TRUE; + psmwp->ccvr = 0; // actualCount + psmwp->ccvrAlloc = Param; // suggestedCount + RETURN((DWORD_PTR)hDwp); + } + case ONEPARAM_ROUTINE_SHOWCURSOR: RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) ); diff --git a/reactos/subsystems/win32/win32k/ntuser/winpos.c b/reactos/subsystems/win32/win32k/ntuser/winpos.c index 6a9dfd2b169..0d6b268bdb0 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winpos.c +++ b/reactos/subsystems/win32/win32k/ntuser/winpos.c @@ -1673,6 +1673,204 @@ co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest) return Window; } +HDWP +FASTCALL +IntDeferWindowPos( HDWP hdwp, + HWND hwnd, + HWND hwndAfter, + INT x, + INT y, + INT cx, + INT cy, + UINT flags ) +{ + PSMWP pDWP; + int i; + HDWP retvalue = hdwp; + + DPRINT("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n", + hdwp, hwnd, hwndAfter, x, y, cx, cy, flags); + + if (flags & ~(SWP_NOSIZE | SWP_NOMOVE | + SWP_NOZORDER | SWP_NOREDRAW | + SWP_NOACTIVATE | SWP_NOCOPYBITS | + SWP_NOOWNERZORDER|SWP_SHOWWINDOW | + SWP_HIDEWINDOW | SWP_FRAMECHANGED)) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP))) + { + EngSetLastError(ERROR_INVALID_DWP_HANDLE); + return NULL; + } + + for (i = 0; i < pDWP->ccvr; i++) + { + if (pDWP->acvr[i].pos.hwnd == hwnd) + { + /* Merge with the other changes */ + if (!(flags & SWP_NOZORDER)) + { + pDWP->acvr[i].pos.hwndInsertAfter = hwndAfter; + } + if (!(flags & SWP_NOMOVE)) + { + pDWP->acvr[i].pos.x = x; + pDWP->acvr[i].pos.y = y; + } + if (!(flags & SWP_NOSIZE)) + { + pDWP->acvr[i].pos.cx = cx; + pDWP->acvr[i].pos.cy = cy; + } + pDWP->acvr[i].pos.flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE | + SWP_NOZORDER | SWP_NOREDRAW | + SWP_NOACTIVATE | SWP_NOCOPYBITS| + SWP_NOOWNERZORDER); + pDWP->acvr[i].pos.flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | + SWP_FRAMECHANGED); + goto END; + } + } + if (pDWP->ccvr >= pDWP->ccvrAlloc) + { + PCVR newpos = ExAllocatePoolWithTag(PagedPool, pDWP->ccvrAlloc * 2 * sizeof(CVR), USERTAG_SWP); + if (!newpos) + { + retvalue = NULL; + goto END; + } + RtlZeroMemory(newpos, pDWP->ccvrAlloc * 2 * sizeof(CVR)); + RtlCopyMemory(newpos, pDWP->acvr, pDWP->ccvrAlloc * sizeof(CVR)); + ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP); + pDWP->ccvrAlloc *= 2; + pDWP->acvr = newpos; + } + pDWP->acvr[pDWP->ccvr].pos.hwnd = hwnd; + pDWP->acvr[pDWP->ccvr].pos.hwndInsertAfter = hwndAfter; + pDWP->acvr[pDWP->ccvr].pos.x = x; + pDWP->acvr[pDWP->ccvr].pos.y = y; + pDWP->acvr[pDWP->ccvr].pos.cx = cx; + pDWP->acvr[pDWP->ccvr].pos.cy = cy; + pDWP->acvr[pDWP->ccvr].pos.flags = flags; + pDWP->acvr[pDWP->ccvr].hrgnClip = NULL; + pDWP->acvr[pDWP->ccvr].hrgnInterMonitor = NULL; + pDWP->ccvr++; +END: + return retvalue; +} + +BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp ) +{ + PSMWP pDWP; + PCVR winpos; + BOOL res = TRUE; + int i; + + DPRINT("%p\n", hdwp); + + if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP))) + { + EngSetLastError(ERROR_INVALID_DWP_HANDLE); + return FALSE; + } + + for (i = 0, winpos = pDWP->acvr; res && i < pDWP->ccvr; i++, winpos++) + { + DPRINT("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n", + winpos->pos.hwnd, winpos->pos.hwndInsertAfter, winpos->pos.x, winpos->pos.y, + winpos->pos.cx, winpos->pos.cy, winpos->pos.flags); + + res = co_WinPosSetWindowPos( UserGetWindowObject(winpos->pos.hwnd), + winpos->pos.hwndInsertAfter, + winpos->pos.x, + winpos->pos.y, + winpos->pos.cx, + winpos->pos.cy, + winpos->pos.flags); + } + ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP); + UserDeleteObject(hdwp, otSMWP); + return res; +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserEndDeferWindowPosEx(HDWP WinPosInfo, + DWORD Unknown1) +{ + BOOL Ret; + DPRINT("Enter NtUserEndDeferWindowPosEx\n"); + UserEnterExclusive(); + Ret = IntEndDeferWindowPosEx(WinPosInfo); + DPRINT("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret); + UserLeave(); + return Ret; +} + +/* + * @implemented + */ +HDWP APIENTRY +NtUserDeferWindowPos(HDWP WinPosInfo, + HWND Wnd, + HWND WndInsertAfter, + int x, + int y, + int cx, + int cy, + UINT Flags) +{ + PWND pWnd, pWndIA; + HDWP Ret = NULL; + UINT Tmp = ~(SWP_ASYNCWINDOWPOS|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_NOREPOSITION| + SWP_NOCOPYBITS|SWP_HIDEWINDOW|SWP_SHOWWINDOW|SWP_FRAMECHANGED| + SWP_NOACTIVATE|SWP_NOREDRAW|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE); + + DPRINT("Enter NtUsereferWindowPos\n"); + UserEnterExclusive(); + + if ( Flags & Tmp ) + { + EngSetLastError(ERROR_INVALID_FLAGS); + goto Exit; + } + + pWnd = UserGetWindowObject(Wnd); + if ( !pWnd || + pWnd == IntGetDesktopWindow() || + pWnd == IntGetMessageWindow() ) + { + goto Exit; + } + + if ( WndInsertAfter && + WndInsertAfter != HWND_BOTTOM && + WndInsertAfter != HWND_TOPMOST && + WndInsertAfter != HWND_NOTOPMOST ) + { + pWndIA = UserGetWindowObject(WndInsertAfter); + if ( !pWndIA || + pWndIA == IntGetDesktopWindow() || + pWndIA == IntGetMessageWindow() ) + { + goto Exit; + } + } + + Ret = IntDeferWindowPos(WinPosInfo, Wnd, WndInsertAfter, x, y, cx, cy, Flags); + +Exit: + DPRINT("Leave NtUserDeferWindowPos, ret=%i\n", Ret); + UserLeave(); + return Ret; +} + BOOL APIENTRY NtUserGetMinMaxInfo( From 5f2514cd75fd2596a3dcf403c99b2263bfff53ac Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 19 Mar 2011 13:59:23 +0000 Subject: [PATCH 28/90] [HAL] Remove HAL entry point (HalInitSystem) from generic lib, and move it to generic libs that handle different build flags. This fixes HAL MP entry point, for example svn path=/trunk/; revision=51090 --- reactos/hal/halx86/hal_generic.rbuild | 1 - reactos/hal/halx86/hal_generic_acpi.rbuild | 3 +++ reactos/hal/halx86/hal_generic_pcat.rbuild | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/reactos/hal/halx86/hal_generic.rbuild b/reactos/hal/halx86/hal_generic.rbuild index 0cd4e5aac43..9b697bbb094 100644 --- a/reactos/hal/halx86/hal_generic.rbuild +++ b/reactos/hal/halx86/hal_generic.rbuild @@ -21,7 +21,6 @@ usage.c bios.c - halinit.c portio.c systimer.S diff --git a/reactos/hal/halx86/hal_generic_acpi.rbuild b/reactos/hal/halx86/hal_generic_acpi.rbuild index babc0e8dfd1..19e2b8093b2 100644 --- a/reactos/hal/halx86/hal_generic_acpi.rbuild +++ b/reactos/hal/halx86/hal_generic_acpi.rbuild @@ -18,6 +18,9 @@ pcibus.c + + halinit.c + diff --git a/reactos/hal/halx86/hal_generic_pcat.rbuild b/reactos/hal/halx86/hal_generic_pcat.rbuild index 51f46eefc71..3ae5c2a4779 100644 --- a/reactos/hal/halx86/hal_generic_pcat.rbuild +++ b/reactos/hal/halx86/hal_generic_pcat.rbuild @@ -19,6 +19,9 @@ bussupp.c halpcat.c + + halinit.c + From fb3cc815f71086390a17c7f2f77b53cae579260f Mon Sep 17 00:00:00 2001 From: Olaf Siejka Date: Sat, 19 Mar 2011 14:11:37 +0000 Subject: [PATCH 29/90] [DESK.CPL] - Activate "Show window contents while dragging" button for all languages present. Spotted by Piotr_hh See issue #6002 for more details. svn path=/trunk/; revision=51091 --- reactos/dll/cpl/desk/lang/bg-BG.rc | 2 +- reactos/dll/cpl/desk/lang/cs-CZ.rc | 2 +- reactos/dll/cpl/desk/lang/el-GR.rc | 2 +- reactos/dll/cpl/desk/lang/fr-FR.rc | 2 +- reactos/dll/cpl/desk/lang/hu-HU.rc | 2 +- reactos/dll/cpl/desk/lang/id-ID.rc | 2 +- reactos/dll/cpl/desk/lang/it-IT.rc | 2 +- reactos/dll/cpl/desk/lang/nl-NL.rc | 2 +- reactos/dll/cpl/desk/lang/no-NO.rc | 2 +- reactos/dll/cpl/desk/lang/pl-PL.rc | 2 +- reactos/dll/cpl/desk/lang/ro-RO.rc | 2 +- reactos/dll/cpl/desk/lang/ru-RU.rc | 2 +- reactos/dll/cpl/desk/lang/sk-SK.rc | 2 +- reactos/dll/cpl/desk/lang/sv-SE.rc | 2 +- reactos/dll/cpl/desk/lang/uk-UA.rc | 2 +- reactos/dll/cpl/desk/lang/zh-CN.rc | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/reactos/dll/cpl/desk/lang/bg-BG.rc b/reactos/dll/cpl/desk/lang/bg-BG.rc index ad7e006fb9d..bf54e27e10e 100644 --- a/reactos/dll/cpl/desk/lang/bg-BG.rc +++ b/reactos/dll/cpl/desk/lang/bg-BG.rc @@ -116,7 +116,7 @@ BEGIN CONTROL "Čçîáđŕç˙âŕíĺ íŕ &ńĺíęč ďîä čçáîđíčöňĺ",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Ďîęŕçâŕíĺ íŕ ńúäúđćŕíčĺňî íŕ &ďđîçîđöčňĺ ďî âđĺěĺ íŕ âëŕ÷ĺíĺ",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "Ń&ęđčâŕíĺ íŕ ďîä÷ĺđňŕâŕíĺňî çŕ ęëŕâčŕňóđíîňî íŕńî÷âŕíĺ, äî íŕňčńęŕíĺ íŕ Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Îňęŕç", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/cs-CZ.rc b/reactos/dll/cpl/desk/lang/cs-CZ.rc index 0ca4627f511..717e214d7d8 100644 --- a/reactos/dll/cpl/desk/lang/cs-CZ.rc +++ b/reactos/dll/cpl/desk/lang/cs-CZ.rc @@ -119,7 +119,7 @@ BEGIN CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/el-GR.rc b/reactos/dll/cpl/desk/lang/el-GR.rc index e9988ab2b53..9c832b0846b 100644 --- a/reactos/dll/cpl/desk/lang/el-GR.rc +++ b/reactos/dll/cpl/desk/lang/el-GR.rc @@ -112,7 +112,7 @@ BEGIN CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/fr-FR.rc b/reactos/dll/cpl/desk/lang/fr-FR.rc index 1158e2cde64..0bdebbc73ed 100644 --- a/reactos/dll/cpl/desk/lang/fr-FR.rc +++ b/reactos/dll/cpl/desk/lang/fr-FR.rc @@ -115,7 +115,7 @@ BEGIN CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/hu-HU.rc b/reactos/dll/cpl/desk/lang/hu-HU.rc index 874408398e1..202fe1559fd 100644 --- a/reactos/dll/cpl/desk/lang/hu-HU.rc +++ b/reactos/dll/cpl/desk/lang/hu-HU.rc @@ -113,7 +113,7 @@ BEGIN CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/id-ID.rc b/reactos/dll/cpl/desk/lang/id-ID.rc index c081f87009c..be3a3803d0f 100644 --- a/reactos/dll/cpl/desk/lang/id-ID.rc +++ b/reactos/dll/cpl/desk/lang/id-ID.rc @@ -112,7 +112,7 @@ BEGIN CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/it-IT.rc b/reactos/dll/cpl/desk/lang/it-IT.rc index 7e21fbc95ed..3ffdf49c497 100644 --- a/reactos/dll/cpl/desk/lang/it-IT.rc +++ b/reactos/dll/cpl/desk/lang/it-IT.rc @@ -112,7 +112,7 @@ BEGIN CONTROL "&Ombreggiatura sotto i menu",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Mostrare il contenuto delle finestr mentre le si trascina",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Nascondere la sottolineatura delle lettere di navigazione finche non č premuto il tasto Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Annulla", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/nl-NL.rc b/reactos/dll/cpl/desk/lang/nl-NL.rc index 74f1842a013..9165bcecee1 100644 --- a/reactos/dll/cpl/desk/lang/nl-NL.rc +++ b/reactos/dll/cpl/desk/lang/nl-NL.rc @@ -114,7 +114,7 @@ BEGIN CONTROL "Sch&aduw onder menu's weergeven",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "De in&houd van het venster tijdens het slepen weergeven",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "Onderstreepte letters voor toetsenbordnavigatie &verbergen tot ALT wordt ingedrukt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Annuleren", IDCANCEL, 246, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/no-NO.rc b/reactos/dll/cpl/desk/lang/no-NO.rc index 61edf39a2fd..5c6494fa9e6 100644 --- a/reactos/dll/cpl/desk/lang/no-NO.rc +++ b/reactos/dll/cpl/desk/lang/no-NO.rc @@ -114,7 +114,7 @@ BEGIN CONTROL "Vis sk&ygger under menyer",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Vis &vindu innholdet ved flytting",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Skjul visning av understrekning for tastatur hurtigtast til jeg trykker pĺ Alt tasten",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Avbryt", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/pl-PL.rc b/reactos/dll/cpl/desk/lang/pl-PL.rc index 436b9d40f6c..80c38df7b7d 100644 --- a/reactos/dll/cpl/desk/lang/pl-PL.rc +++ b/reactos/dll/cpl/desk/lang/pl-PL.rc @@ -122,7 +122,7 @@ BEGIN CONTROL "Pok&aż cienie pod menu",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Pokaż za&wartość okna podczas przeciągania",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "U&kryj podkreślenie liter do nawigacji klawiaturą dopóki nie nacisnę klawisza Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Anuluj", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/ro-RO.rc b/reactos/dll/cpl/desk/lang/ro-RO.rc index 39b0b41c41e..e74329a20f0 100644 --- a/reactos/dll/cpl/desk/lang/ro-RO.rc +++ b/reactos/dll/cpl/desk/lang/ro-RO.rc @@ -116,7 +116,7 @@ BEGIN CONTROL "AfiČ™are u&mbre sub meniuri",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "AfiČ™are c&onČ›inut al ferestrelor când sunt trase",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Ascundere litere subliniate pentru navigarea cu tastatura pânÄ când apÄs Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Anulare", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/ru-RU.rc b/reactos/dll/cpl/desk/lang/ru-RU.rc index 519da21015f..dad783a73ee 100644 --- a/reactos/dll/cpl/desk/lang/ru-RU.rc +++ b/reactos/dll/cpl/desk/lang/ru-RU.rc @@ -112,7 +112,7 @@ BEGIN CONTROL "Îňîáđŕćŕňü &ňĺíč, îňáđŕńűâŕĺěűĺ ěĺíţ",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "&Îňîáđŕćŕňü ńîäĺđćčěîĺ îęíŕ ďđč ďĺđĺňŕńęčâŕíčč",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "Ńęđ&űâŕňü óęŕçŕňĺëč âűçîâŕ ń ęëŕâčŕňóđű äî íŕćŕňč˙ ",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Îňěĺíŕ", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/sk-SK.rc b/reactos/dll/cpl/desk/lang/sk-SK.rc index 0743898065c..ec8bfcee042 100644 --- a/reactos/dll/cpl/desk/lang/sk-SK.rc +++ b/reactos/dll/cpl/desk/lang/sk-SK.rc @@ -122,7 +122,7 @@ BEGIN CONTROL "&Zobrazovať tiene pod ponukami",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Zobrazovať &obsah okna počas presúvania",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Skrývať podčiarknuté písmená (klávesové skratky) až do stlačenia klávesu Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Zrušiť", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/sv-SE.rc b/reactos/dll/cpl/desk/lang/sv-SE.rc index 49f8c7bda2c..b73e7fa6ca6 100644 --- a/reactos/dll/cpl/desk/lang/sv-SE.rc +++ b/reactos/dll/cpl/desk/lang/sv-SE.rc @@ -115,7 +115,7 @@ BEGIN CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/uk-UA.rc b/reactos/dll/cpl/desk/lang/uk-UA.rc index bcbefe72481..ff8888a85a9 100644 --- a/reactos/dll/cpl/desk/lang/uk-UA.rc +++ b/reactos/dll/cpl/desk/lang/uk-UA.rc @@ -120,7 +120,7 @@ BEGIN CONTROL "Âłäîáđŕćŕňč ňłíł âłä ěĺíţ",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Ďîęŕçŕňč &âěłńň âłęíŕ ďłä ÷ŕń ďĺđĺň˙ăóâŕíí˙",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Ďđčőîâóâŕňč ďîęŕć÷čęč âčęëčęó ç ęëŕâłŕňóđč äî íŕňčńíĺíí˙ ",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Ńęŕńóâŕňč", IDCANCEL, 226, 165, 50, 14 diff --git a/reactos/dll/cpl/desk/lang/zh-CN.rc b/reactos/dll/cpl/desk/lang/zh-CN.rc index f09d566fa7f..0cd960d51ca 100644 --- a/reactos/dll/cpl/desk/lang/zh-CN.rc +++ b/reactos/dll/cpl/desk/lang/zh-CN.rc @@ -121,7 +121,7 @@ BEGIN CONTROL "Ôڲ˵ĄĎÂĎÔĘľŇőÓ°(&A)",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 CONTROL "Í϶ŻĘ±ĎÔĘľ´°żÚÄÚČÝ(&W)",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "Ö±µ˝ÎҰ´ Alt ĽüÖ®Ç°Ł¬ÇëŇţ˛ŘÓĐĎ»®ĎßµÄ×ÖÄ¸ą©ĽüĹĚĘąÓĂ",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "ȡĎű", IDCANCEL, 226, 165, 50, 14 From 80b43e7b1371c0b7269185689758f5e1a4488611 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 19 Mar 2011 19:14:53 +0000 Subject: [PATCH 30/90] [SERVICES] RQueryServiceConfig2A/W must return ERROR_SUCCESS if the Description value of a service does not exist. This fixes a winetest failure. svn path=/trunk/; revision=51092 --- reactos/base/system/services/rpcserver.c | 69 +++++++++++++----------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index cc45ff5f1e4..9c42b81cfa0 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -4558,42 +4558,40 @@ DWORD RQueryServiceConfig2A( LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer; LPSTR lpStr; - *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA); - dwError = ScmReadString(hServiceKey, L"Description", &lpDescriptionW); + if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND) + goto done; + + *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA); if (dwError == ERROR_SUCCESS) - { *pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR)); + + if (cbBufSize < *pcbBytesNeeded) + { + dwError = ERROR_INSUFFICIENT_BUFFER; + goto done; } - if (cbBufSize >= *pcbBytesNeeded) + if (dwError == ERROR_SUCCESS) { + lpStr = (LPSTR)(lpServiceDescription + 1); - if (dwError == ERROR_SUCCESS) - { - lpStr = (LPSTR)(lpServiceDescription + 1); - - WideCharToMultiByte(CP_ACP, - 0, - lpDescriptionW, - -1, - lpStr, - wcslen(lpDescriptionW), - NULL, - NULL); - lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription); - } - else - { - lpServiceDescription->lpDescription = NULL; - goto done; - } + WideCharToMultiByte(CP_ACP, + 0, + lpDescriptionW, + -1, + lpStr, + wcslen(lpDescriptionW), + NULL, + NULL); + lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription); } else { - dwError = ERROR_INSUFFICIENT_BUFFER; + lpServiceDescription->lpDescription = NULL; + dwError = ERROR_SUCCESS; goto done; } } @@ -4681,21 +4679,30 @@ DWORD RQueryServiceConfig2W( dwError = ScmReadString(hServiceKey, L"Description", &lpDescription); - if (dwError != ERROR_SUCCESS) + if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND) goto done; - dwRequiredSize = sizeof(SERVICE_DESCRIPTIONW) + ((wcslen(lpDescription) + 1) * sizeof(WCHAR)); + *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONW); + if (dwError == ERROR_SUCCESS) + *pcbBytesNeeded += ((wcslen(lpDescription) + 1) * sizeof(WCHAR)); - if (cbBufSize < dwRequiredSize) + if (cbBufSize < *pcbBytesNeeded) { - *pcbBytesNeeded = dwRequiredSize; dwError = ERROR_INSUFFICIENT_BUFFER; goto done; } - lpStr = (LPWSTR)(lpServiceDescription + 1); - wcscpy(lpStr, lpDescription); - lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription); + if (dwError == ERROR_SUCCESS) + { + lpStr = (LPWSTR)(lpServiceDescription + 1); + wcscpy(lpStr, lpDescription); + lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription); + } + else + { + lpServiceDescription->lpDescription = NULL; + dwError = ERROR_SUCCESS; + } } else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS) { From f106ac2d2bf2095f95c0b9b9ed250e37e2cadc9c Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 20 Mar 2011 00:21:45 +0000 Subject: [PATCH 31/90] [Win32k] - Fix sign for BeginDeferWindowPos(-1) test, see bug 6025. svn path=/trunk/; revision=51093 --- reactos/subsystems/win32/win32k/ntuser/simplecall.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/simplecall.c b/reactos/subsystems/win32/win32k/ntuser/simplecall.c index 1e74111f4f5..87d8c07dc3a 100644 --- a/reactos/subsystems/win32/win32k/ntuser/simplecall.c +++ b/reactos/subsystems/win32/win32k/ntuser/simplecall.c @@ -162,13 +162,15 @@ NtUserCallOneParam( { PSMWP psmwp; HDWP hDwp = NULL; - if (Param < 0) + INT count = (INT)Param; + + if (count < 0) { EngSetLastError(ERROR_INVALID_PARAMETER); RETURN(0); } /* Windows allows zero count, in which case it allocates context for 8 moves */ - if (Param == 0) Param = 8; + if (count == 0) count = 8; psmwp = (PSMWP) UserCreateObject( gHandleTable, NULL, @@ -176,13 +178,13 @@ NtUserCallOneParam( otSMWP, sizeof(SMWP)); if (!psmwp) RETURN(0); - psmwp->acvr = ExAllocatePoolWithTag(PagedPool, Param * sizeof(CVR), USERTAG_SWP); + psmwp->acvr = ExAllocatePoolWithTag(PagedPool, count * sizeof(CVR), USERTAG_SWP); if (!psmwp->acvr) { UserDeleteObject(hDwp, otSMWP); RETURN(0); } - RtlZeroMemory(psmwp->acvr, Param * sizeof(CVR)); + RtlZeroMemory(psmwp->acvr, count * sizeof(CVR)); psmwp->bHandle = TRUE; psmwp->ccvr = 0; // actualCount psmwp->ccvrAlloc = Param; // suggestedCount From 1b6ac48af4273d623894193fe5187d828b641b80 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 20 Mar 2011 01:09:15 +0000 Subject: [PATCH 32/90] [Win32k] - Move the appropriate code from window.c to winpos.c, decreasing the size in window.c. Adding proper checks for maximums and desktop/message windows. - Started MinMaximize, experimental, based on an idea and boredom, needing a good test case. Also away of troubleshooting our window positioning with minimize and maximizing windows. svn path=/trunk/; revision=51094 --- .../subsystems/win32/win32k/ntuser/ntstubs.c | 41 ++- .../subsystems/win32/win32k/ntuser/window.c | 245 --------------- .../subsystems/win32/win32k/ntuser/winpos.c | 295 +++++++++++++++++- 3 files changed, 324 insertions(+), 257 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c index 774ee67e84b..1f7615debf2 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c @@ -817,8 +817,45 @@ NtUserMinMaximize( UINT cmd, // Wine SW_ commands BOOL Hide) { - UNIMPLEMENTED; - return 0; + RECTL NewPos; + UINT SwFlags; + PWND pWnd; + + DPRINT("Enter NtUserMinMaximize\n"); + UserEnterExclusive(); + + pWnd = UserGetWindowObject(hWnd); + if ( !pWnd || // FIXME: + pWnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + pWnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + goto Exit; + } + + if ( cmd > SW_MAX || pWnd->state2 & WNDS2_INDESTROY) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + goto Exit; + } + + co_WinPosMinMaximize(pWnd, cmd, &NewPos); + + SwFlags = Hide ? SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED : SWP_NOZORDER|SWP_FRAMECHANGED; + + co_WinPosSetWindowPos( pWnd, + NULL, + NewPos.left, + NewPos.top, + NewPos.right, + NewPos.bottom, + SwFlags); + + co_WinPosShowWindow(pWnd, cmd); + +Exit: + DPRINT("Leave NtUserMinMaximize\n"); + UserLeave(); + return 0; // Always NULL? } DWORD diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 7be4ef57280..4d80898aa0a 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -3684,23 +3684,6 @@ CLEANUP: END_CLEANUP; } -/* - * @implemented - */ -BOOL APIENTRY -NtUserMoveWindow( - HWND hWnd, - int X, - int Y, - int nWidth, - int nHeight, - BOOL bRepaint) -{ - return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, - (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE : - SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW)); -} - /* QueryWindow based on KJK::Hyperion and James Tabor. @@ -3901,234 +3884,6 @@ CLEANUP: END_CLEANUP; } - -/* - * @implemented - */ -BOOL APIENTRY -NtUserSetWindowPlacement(HWND hWnd, - WINDOWPLACEMENT *lpwndpl) -{ - PWND Wnd; - WINDOWPLACEMENT Safepl; - NTSTATUS Status; - DECLARE_RETURN(BOOL); - USER_REFERENCE_ENTRY Ref; - - DPRINT("Enter NtUserSetWindowPlacement\n"); - UserEnterExclusive(); - - if (!(Wnd = UserGetWindowObject(hWnd))) - { - RETURN( FALSE); - } - - Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT)); - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( FALSE); - } - if(Safepl.length != sizeof(WINDOWPLACEMENT)) - { - RETURN( FALSE); - } - - UserRefObjectCo(Wnd, &Ref); - - if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0) - { - co_WinPosSetWindowPos(Wnd, NULL, - Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top, - Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left, - Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top, - SWP_NOZORDER | SWP_NOACTIVATE); - } - - /* FIXME - change window status */ - co_WinPosShowWindow(Wnd, Safepl.showCmd); - - Wnd->InternalPosInitialized = TRUE; - Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition; - Wnd->InternalPos.IconPos = Safepl.ptMinPosition; - Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition; - - UserDerefObjectCo(Wnd); - RETURN(TRUE); - -CLEANUP: - DPRINT("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - - -/* - * @implemented - */ -BOOL APIENTRY -NtUserSetWindowPos( - HWND hWnd, - HWND hWndInsertAfter, - int X, - int Y, - int cx, - int cy, - UINT uFlags) -{ - DECLARE_RETURN(BOOL); - PWND Window; - BOOL ret; - USER_REFERENCE_ENTRY Ref; - - DPRINT("Enter NtUserSetWindowPos\n"); - UserEnterExclusive(); - - if (!(Window = UserGetWindowObject(hWnd))) - { - RETURN(FALSE); - } - - /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */ - if (!(uFlags & SWP_NOMOVE)) - { - if (X < -32768) X = -32768; - else if (X > 32767) X = 32767; - if (Y < -32768) Y = -32768; - else if (Y > 32767) Y = 32767; - } - if (!(uFlags & SWP_NOSIZE)) - { - if (cx < 0) cx = 0; - else if (cx > 32767) cx = 32767; - if (cy < 0) cy = 0; - else if (cy > 32767) cy = 32767; - } - - UserRefObjectCo(Window, &Ref); - ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags); - UserDerefObjectCo(Window); - - RETURN(ret); - -CLEANUP: - DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - -/* - * @implemented - */ -INT APIENTRY -NtUserSetWindowRgn( - HWND hWnd, - HRGN hRgn, - BOOL bRedraw) -{ - HRGN hrgnCopy; - PWND Window; - INT flags = (SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE); - BOOLEAN Ret = FALSE; - DECLARE_RETURN(INT); - - DPRINT("Enter NtUserSetWindowRgn\n"); - UserEnterExclusive(); - - if (!(Window = UserGetWindowObject(hWnd))) - { - RETURN( 0); - } - - if (hRgn) // The region will be deleted in user32. - { - if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION)) - { - hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0); - - NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY); - } - else - RETURN( 0); - } - else - { - hrgnCopy = NULL; - } - - if (Window->hrgnClip) - { - /* Delete no longer needed region handle */ - GreDeleteObject(Window->hrgnClip); - } - - if (hrgnCopy) - { - if (Window->fnid != FNID_DESKTOP) - NtGdiOffsetRgn(hrgnCopy, Window->rcWindow.left, Window->rcWindow.top); - - /* Set public ownership */ - IntGdiSetRegionOwner(hrgnCopy, GDI_OBJ_HMGR_PUBLIC); - } - Window->hrgnClip = hrgnCopy; - - Ret = co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, bRedraw ? flags : (flags|SWP_NOREDRAW) ); - - RETURN( (INT)Ret); - -CLEANUP: - DPRINT("Leave NtUserSetWindowRgn, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - - -/* - * @implemented - */ -BOOL APIENTRY -NtUserShowWindow(HWND hWnd, LONG nCmdShow) -{ - PWND Window; - BOOL ret; - DECLARE_RETURN(BOOL); - USER_REFERENCE_ENTRY Ref; - - DPRINT("Enter NtUserShowWindow\n"); - UserEnterExclusive(); - - if (!(Window = UserGetWindowObject(hWnd))) - { - RETURN(FALSE); - } - - UserRefObjectCo(Window, &Ref); - ret = co_WinPosShowWindow(Window, nCmdShow); - UserDerefObjectCo(Window); - - RETURN(ret); - -CLEANUP: - DPRINT("Leave NtUserShowWindow, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - - -/* - * @unimplemented - */ -BOOL APIENTRY -NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow) -{ -#if 0 - UNIMPLEMENTED - return 0; -#else - return NtUserShowWindow(hWnd, nCmdShow); -#endif -} - /* * @implemented */ diff --git a/reactos/subsystems/win32/win32k/ntuser/winpos.c b/reactos/subsystems/win32/win32k/ntuser/winpos.c index 0d6b268bdb0..3934dcb21b6 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winpos.c +++ b/reactos/subsystems/win32/win32k/ntuser/winpos.c @@ -20,7 +20,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Windows - * FILE: subsys/win32k/ntuser/window.c + * FILE: subsystems/win32/win32k/ntuser/window.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * REVISION HISTORY: * 06-06-2001 CSH NtGdid @@ -199,8 +199,8 @@ co_WinPosArrangeIconicWindows(PWND parent) x = rectParent.left; y = rectParent.bottom; - xspacing = UserGetSystemMetrics(SM_CXMINSPACING); - yspacing = UserGetSystemMetrics(SM_CYMINSPACING); + xspacing = UserGetSystemMetrics(SM_CXICONSPACING); + yspacing = UserGetSystemMetrics(SM_CYICONSPACING); DPRINT("X:%d Y:%d XS:%d YS:%d\n",x,y,xspacing,yspacing); @@ -216,8 +216,8 @@ co_WinPosArrangeIconicWindows(PWND parent) USER_REFERENCE_ENTRY Ref; UserRefObjectCo(Child, &Ref); - co_WinPosSetWindowPos(Child, 0, x + UserGetSystemMetrics(SM_CXBORDER), - y - yspacing - UserGetSystemMetrics(SM_CYBORDER) + co_WinPosSetWindowPos(Child, 0, x + (xspacing - UserGetSystemMetrics(SM_CXICON)) / 2, + y - yspacing - UserGetSystemMetrics(SM_CYICON) / 2 , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); UserDerefObjectCo(Child); @@ -239,7 +239,7 @@ co_WinPosArrangeIconicWindows(PWND parent) static VOID FASTCALL WinPosFindIconPos(PWND Window, POINT *Pos) { - /* FIXME */ + DPRINT1("WinPosFindIconPos FIXME!\n"); } VOID FASTCALL @@ -1832,7 +1832,7 @@ NtUserDeferWindowPos(HDWP WinPosInfo, SWP_NOCOPYBITS|SWP_HIDEWINDOW|SWP_SHOWWINDOW|SWP_FRAMECHANGED| SWP_NOACTIVATE|SWP_NOREDRAW|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE); - DPRINT("Enter NtUsereferWindowPos\n"); + DPRINT("Enter NtUserDeferWindowPos\n"); UserEnterExclusive(); if ( Flags & Tmp ) @@ -1842,9 +1842,9 @@ NtUserDeferWindowPos(HDWP WinPosInfo, } pWnd = UserGetWindowObject(Wnd); - if ( !pWnd || - pWnd == IntGetDesktopWindow() || - pWnd == IntGetMessageWindow() ) + if ( !pWnd || // FIXME: + pWnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + pWnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND { goto Exit; } @@ -1871,6 +1871,281 @@ Exit: return Ret; } +/* + * @implemented + */ +BOOL APIENTRY +NtUserMoveWindow( + HWND hWnd, + int X, + int Y, + int nWidth, + int nHeight, + BOOL bRepaint) +{ + return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, + (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE : + SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW)); +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserSetWindowPos( + HWND hWnd, + HWND hWndInsertAfter, + int X, + int Y, + int cx, + int cy, + UINT uFlags) +{ + DECLARE_RETURN(BOOL); + PWND Window, pWndIA; + BOOL ret; + USER_REFERENCE_ENTRY Ref; + + DPRINT("Enter NtUserSetWindowPos\n"); + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd)) || // FIXME: + Window == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Window == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + RETURN(FALSE); + } + + if ( hWndInsertAfter && + hWndInsertAfter != HWND_BOTTOM && + hWndInsertAfter != HWND_TOPMOST && + hWndInsertAfter != HWND_NOTOPMOST ) + { + pWndIA = UserGetWindowObject(hWndInsertAfter); + if ( !pWndIA || + pWndIA == IntGetDesktopWindow() || + pWndIA == IntGetMessageWindow() ) + { + RETURN(FALSE); + } + } + + /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */ + if (!(uFlags & SWP_NOMOVE)) + { + if (X < -32768) X = -32768; + else if (X > 32767) X = 32767; + if (Y < -32768) Y = -32768; + else if (Y > 32767) Y = 32767; + } + if (!(uFlags & SWP_NOSIZE)) + { + if (cx < 0) cx = 0; + else if (cx > 32767) cx = 32767; + if (cy < 0) cy = 0; + else if (cy > 32767) cy = 32767; + } + + UserRefObjectCo(Window, &Ref); + ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags); + UserDerefObjectCo(Window); + + RETURN(ret); + +CLEANUP: + DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + +/* + * @implemented + */ +INT APIENTRY +NtUserSetWindowRgn( + HWND hWnd, + HRGN hRgn, + BOOL bRedraw) +{ + HRGN hrgnCopy; + PWND Window; + INT flags = (SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE); + BOOLEAN Ret = FALSE; + DECLARE_RETURN(INT); + + DPRINT("Enter NtUserSetWindowRgn\n"); + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd)) || // FIXME: + Window == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Window == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + RETURN( 0); + } + + if (hRgn) // The region will be deleted in user32. + { + if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION)) + { + hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0); + + NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY); + } + else + RETURN( 0); + } + else + { + hrgnCopy = NULL; + } + + if (Window->hrgnClip) + { + /* Delete no longer needed region handle */ + GreDeleteObject(Window->hrgnClip); + } + + if (hrgnCopy) + { + if (Window->fnid != FNID_DESKTOP) + NtGdiOffsetRgn(hrgnCopy, Window->rcWindow.left, Window->rcWindow.top); + + /* Set public ownership */ + IntGdiSetRegionOwner(hrgnCopy, GDI_OBJ_HMGR_PUBLIC); + } + Window->hrgnClip = hrgnCopy; + + Ret = co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, bRedraw ? flags : (flags|SWP_NOREDRAW) ); + + RETURN( (INT)Ret); + +CLEANUP: + DPRINT("Leave NtUserSetWindowRgn, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserSetWindowPlacement(HWND hWnd, + WINDOWPLACEMENT *lpwndpl) +{ + PWND Wnd; + WINDOWPLACEMENT Safepl; + DECLARE_RETURN(BOOL); + USER_REFERENCE_ENTRY Ref; + + DPRINT("Enter NtUserSetWindowPlacement\n"); + UserEnterExclusive(); + + if (!(Wnd = UserGetWindowObject(hWnd)) || // FIXME: + Wnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Wnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + RETURN( FALSE); + } + + _SEH2_TRY + { + ProbeForRead(lpwndpl, sizeof(WINDOWPLACEMENT), 1); + RtlCopyMemory(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(RETURN( FALSE)); + } + _SEH2_END + + if(Safepl.length != sizeof(WINDOWPLACEMENT)) + { + RETURN( FALSE); + } + + UserRefObjectCo(Wnd, &Ref); + + if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0) + { + co_WinPosSetWindowPos(Wnd, NULL, + Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top, + Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left, + Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top, + SWP_NOZORDER | SWP_NOACTIVATE); + } + + /* FIXME - change window status */ + co_WinPosShowWindow(Wnd, Safepl.showCmd); + + Wnd->InternalPosInitialized = TRUE; + Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition; + Wnd->InternalPos.IconPos = Safepl.ptMinPosition; + Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition; + + UserDerefObjectCo(Wnd); + RETURN(TRUE); + +CLEANUP: + DPRINT("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + +/* + * @unimplemented + */ +BOOL APIENTRY +NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow) +{ +#if 0 + UNIMPLEMENTED + return 0; +#else + return NtUserShowWindow(hWnd, nCmdShow); +#endif +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserShowWindow(HWND hWnd, LONG nCmdShow) +{ + PWND Window; + BOOL ret; + DECLARE_RETURN(BOOL); + USER_REFERENCE_ENTRY Ref; + + DPRINT("Enter NtUserShowWindow\n"); + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd)) || // FIXME: + Window == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Window == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + RETURN(FALSE); + } + + if ( nCmdShow > SW_MAX || Window->state2 & WNDS2_INDESTROY) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + RETURN(FALSE); + } + + UserRefObjectCo(Window, &Ref); + ret = co_WinPosShowWindow(Window, nCmdShow); + UserDerefObjectCo(Window); + + RETURN(ret); + +CLEANUP: + DPRINT("Leave NtUserShowWindow, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + +//// Ugly NtUser API //// BOOL APIENTRY NtUserGetMinMaxInfo( From 06afcd3dd6988ba2d744c028371dbf4bc5f0e0da Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 20 Mar 2011 01:29:39 +0000 Subject: [PATCH 33/90] [User32] - Finishing with setting window class types from the window proc. Next step will be checking it in the User32 message exchange instead of using the class structure. This was recognized with the MDI tests, this too could fix the combo listbox issue. - Minor static test fixes and miscellaneous notes. svn path=/trunk/; revision=51095 --- reactos/dll/win32/user32/controls/icontitle.c | 17 ++++++++++ .../dll/win32/user32/controls/regcontrol.c | 17 +++++++++- reactos/dll/win32/user32/controls/scrollbar.c | 19 +++++++++++ reactos/dll/win32/user32/controls/static.c | 3 ++ reactos/dll/win32/user32/windows/menu.c | 33 +++++++++++++++++++ 5 files changed, 88 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/user32/controls/icontitle.c b/reactos/dll/win32/user32/controls/icontitle.c index 467ca076c52..6daf27ec125 100644 --- a/reactos/dll/win32/user32/controls/icontitle.c +++ b/reactos/dll/win32/user32/controls/icontitle.c @@ -189,6 +189,18 @@ LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg, HWND owner = GetWindow( hWnd, GW_OWNER ); if (!IsWindow(hWnd)) return 0; +#ifdef __REACTOS__ // Do this now, remove after Server side is fixed. + PWND pWnd; + + pWnd = ValidateHwnd(hWnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(hWnd, FNID_ICONTITLE); + } + } +#endif switch( msg ) { @@ -201,6 +213,11 @@ LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg, hIconTitleFont = CreateFontIndirectA( &logFont ); } return (hIconTitleFont ? 0 : -1); +#ifdef __REACTOS__ + case WM_DESTROY: + NtUserSetWindowFNID(hWnd, FNID_DESTROY); + break; +#endif case WM_NCHITTEST: return HTCAPTION; case WM_NCMOUSEMOVE: diff --git a/reactos/dll/win32/user32/controls/regcontrol.c b/reactos/dll/win32/user32/controls/regcontrol.c index 47a45cebc7d..9980f06a6df 100644 --- a/reactos/dll/win32/user32/controls/regcontrol.c +++ b/reactos/dll/win32/user32/controls/regcontrol.c @@ -87,8 +87,23 @@ LRESULT WINAPI MsgWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { + PWND pWnd; + + pWnd = ValidateHwnd(hwnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(hwnd, FNID_MESSAGEWND); + } + } + if (message == WM_NCCREATE) return TRUE; - return 0; + + if (message == WM_DESTROY) + NtUserSetWindowFNID(hwnd, FNID_DESTROY); + + return DefWindowProc(hwnd, message, wParam, lParam ); } LRESULT diff --git a/reactos/dll/win32/user32/controls/scrollbar.c b/reactos/dll/win32/user32/controls/scrollbar.c index ad0f4f25729..b238b64532a 100644 --- a/reactos/dll/win32/user32/controls/scrollbar.c +++ b/reactos/dll/win32/user32/controls/scrollbar.c @@ -1248,12 +1248,31 @@ ScrollBarWndProc(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARA return 0; } +#ifdef __REACTOS__ // Do this now, remove after Server side is fixed. + PWND pWnd; + + pWnd = ValidateHwnd(Wnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(Wnd, FNID_SCROLLBAR); + } + } +#endif + switch (Msg) { case WM_CREATE: IntScrollCreateScrollBar(Wnd, (LPCREATESTRUCTW) lParam); break; +#ifdef __REACTOS__ + case WM_DESTROY: + NtUserSetWindowFNID(Wnd, FNID_DESTROY); + return DefWindowProc(Wnd, Msg, wParam, lParam ); +#endif + //#if 0 /* FIXME */ case WM_ENABLE: { diff --git a/reactos/dll/win32/user32/controls/static.c b/reactos/dll/win32/user32/controls/static.c index bc0b92b361c..d421eae4671 100644 --- a/reactos/dll/win32/user32/controls/static.c +++ b/reactos/dll/win32/user32/controls/static.c @@ -813,6 +813,9 @@ static void STATIC_PaintRectfn( HWND hwnd, HDC hdc, DWORD style ) GetClientRect( hwnd, &rc); /* FIXME: send WM_CTLCOLORSTATIC */ +#ifdef __REACTOS__ + hBrush = STATIC_SendWmCtlColorStatic(hwnd, hdc); // Always sent.... +#endif switch (style & SS_TYPEMASK) { case SS_BLACKRECT: diff --git a/reactos/dll/win32/user32/windows/menu.c b/reactos/dll/win32/user32/windows/menu.c index 768cf65c3f3..9b500dbd8a0 100644 --- a/reactos/dll/win32/user32/windows/menu.c +++ b/reactos/dll/win32/user32/windows/menu.c @@ -1792,9 +1792,24 @@ MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset) MenuCleanupRosMenuItemInfo(&ItemInfo); } +// +// This breaks some test results. Should handle A2U if called! +// LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) { TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam); +#ifdef __REACTOS__ + PWND pWnd; + + pWnd = ValidateHwnd(Wnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(Wnd, FNID_MENU); + } + } +#endif switch(Message) { @@ -1834,6 +1849,9 @@ LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM l top_popup = NULL; top_popup_hmenu = NULL; } +#ifdef __REACTOS__ + NtUserSetWindowFNID(Wnd, FNID_DESTROY); +#endif break; case WM_SHOWWINDOW: @@ -1868,6 +1886,18 @@ LRESULT WINAPI PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) { TRACE("hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam); +#ifdef __REACTOS__ // Do this now, remove after Server side is fixed. + PWND pWnd; + + pWnd = ValidateHwnd(Wnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(Wnd, FNID_MENU); + } + } +#endif switch(Message) { @@ -1907,6 +1937,9 @@ PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) top_popup = NULL; top_popup_hmenu = NULL; } +#ifdef __REACTOS__ + NtUserSetWindowFNID(Wnd, FNID_DESTROY); +#endif break; case WM_SHOWWINDOW: From 7dfa68869c4a6e087ed26ca2db52ea44cf033f63 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 20 Mar 2011 08:47:41 +0000 Subject: [PATCH 34/90] [msi] -partial sync to wine 1.3.16 svn path=/trunk/; revision=51096 --- reactos/dll/win32/msi/action.c | 1502 +++++++++++++-------------- reactos/dll/win32/msi/appsearch.c | 10 +- reactos/dll/win32/msi/assembly.c | 629 +++++++++++ reactos/dll/win32/msi/classes.c | 15 +- reactos/dll/win32/msi/cond.tab.c | 54 +- reactos/dll/win32/msi/cond.y | 54 +- reactos/dll/win32/msi/create.c | 3 +- reactos/dll/win32/msi/custom.c | 155 +-- reactos/dll/win32/msi/database.c | 57 +- reactos/dll/win32/msi/dialog.c | 86 +- reactos/dll/win32/msi/events.c | 91 +- reactos/dll/win32/msi/files.c | 271 +++-- reactos/dll/win32/msi/font.c | 55 +- reactos/dll/win32/msi/format.c | 7 +- reactos/dll/win32/msi/helpers.c | 189 ++-- reactos/dll/win32/msi/insert.c | 5 +- reactos/dll/win32/msi/install.c | 58 +- reactos/dll/win32/msi/media.c | 60 +- reactos/dll/win32/msi/msi.c | 253 +++-- reactos/dll/win32/msi/msi.rbuild | 1 + reactos/dll/win32/msi/msi.rc | 82 +- reactos/dll/win32/msi/msi.spec | 2 +- reactos/dll/win32/msi/msi_main.c | 36 +- reactos/dll/win32/msi/msipriv.h | 164 +-- reactos/dll/win32/msi/msiquery.c | 4 +- reactos/dll/win32/msi/msiserver.idl | 101 ++ reactos/dll/win32/msi/package.c | 159 ++- reactos/dll/win32/msi/record.c | 3 +- reactos/dll/win32/msi/registry.c | 22 +- reactos/dll/win32/msi/script.c | 1 + reactos/dll/win32/msi/source.c | 33 +- reactos/dll/win32/msi/sql.tab.c | 2 +- reactos/dll/win32/msi/sql.y | 2 +- reactos/dll/win32/msi/string.c | 34 +- reactos/dll/win32/msi/table.c | 88 +- reactos/dll/win32/msi/where.c | 7 +- 36 files changed, 2657 insertions(+), 1638 deletions(-) create mode 100644 reactos/dll/win32/msi/assembly.c diff --git a/reactos/dll/win32/msi/action.c b/reactos/dll/win32/msi/action.c index 808386f96e9..f806f18cb34 100644 --- a/reactos/dll/win32/msi/action.c +++ b/reactos/dll/win32/msi/action.c @@ -35,7 +35,6 @@ #include "shlobj.h" #include "objbase.h" #include "mscoree.h" -#include "fusion.h" #include "shlwapi.h" #include "wine/unicode.h" #include "winver.h" @@ -110,8 +109,6 @@ static const WCHAR szIsolateComponents[] = {'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t','s',0}; static const WCHAR szMigrateFeatureStates[] = {'M','i','g','r','a','t','e','F','e','a','t','u','r','e','S','t','a','t','e','s',0}; -static const WCHAR szMsiPublishAssemblies[] = - {'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0}; static const WCHAR szMsiUnpublishAssemblies[] = {'M','s','i','U','n','p','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0}; static const WCHAR szInstallODBC[] = @@ -165,10 +162,6 @@ static const WCHAR szValidateProductID[] = static const WCHAR szWriteEnvironmentStrings[] = {'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0}; -/******************************************************** - * helper functions - ********************************************************/ - static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action) { static const WCHAR Query_t[] = @@ -214,86 +207,173 @@ static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, msiobj_release(&row->hdr); } +enum parse_state +{ + state_whitespace, + state_token, + state_quote +}; + +static int parse_prop( const WCHAR *str, WCHAR *value, int *quotes ) +{ + enum parse_state state = state_quote; + const WCHAR *p; + WCHAR *out = value; + int ignore, in_quotes = 0, count = 0, len = 0; + + for (p = str; *p; p++) + { + ignore = 0; + switch (state) + { + case state_whitespace: + switch (*p) + { + case ' ': + if (!count) goto done; + in_quotes = 1; + ignore = 1; + break; + case '"': + state = state_quote; + if (in_quotes) count--; + else count++; + break; + default: + state = state_token; + if (!count) in_quotes = 0; + else in_quotes = 1; + len++; + break; + } + break; + + case state_token: + switch (*p) + { + case '"': + state = state_quote; + if (in_quotes) count--; + else count++; + break; + case ' ': + state = state_whitespace; + if (!count) goto done; + in_quotes = 1; + break; + default: + if (!count) in_quotes = 0; + else in_quotes = 1; + len++; + break; + } + break; + + case state_quote: + switch (*p) + { + case '"': + if (in_quotes) count--; + else count++; + break; + case ' ': + state = state_whitespace; + if (!count || !len) goto done; + in_quotes = 1; + break; + default: + state = state_token; + if (!count) in_quotes = 0; + else in_quotes = 1; + len++; + break; + } + break; + + default: break; + } + if (!ignore) *out++ = *p; + } + +done: + if (!len) *value = 0; + else *out = 0; + + *quotes = count; + return p - str; +} + +static void remove_quotes( WCHAR *str ) +{ + WCHAR *p = str; + int len = strlenW( str ); + + while ((p = strchrW( p, '"' ))) + { + memmove( p, p + 1, (len - (p - str)) * sizeof(WCHAR) ); + p++; + } +} + UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine, BOOL preserve_case ) { - LPCWSTR ptr,ptr2; - BOOL quote; + LPCWSTR ptr, ptr2; + int quotes; DWORD len; - LPWSTR prop = NULL, val = NULL; + WCHAR *prop, *val; + UINT r; if (!szCommandLine) return ERROR_SUCCESS; ptr = szCommandLine; - while (*ptr) { - if (*ptr==' ') - { - ptr++; - continue; - } + while (*ptr == ' ') ptr++; + if (!*ptr) break; - TRACE("Looking at %s\n",debugstr_w(ptr)); - - ptr2 = strchrW(ptr,'='); - if (!ptr2) - { - ERR("command line contains unknown string : %s\n", debugstr_w(ptr)); - break; - } + ptr2 = strchrW( ptr, '=' ); + if (!ptr2) return ERROR_INVALID_COMMAND_LINE; - quote = FALSE; + len = ptr2 - ptr; + if (!len) return ERROR_INVALID_COMMAND_LINE; - len = ptr2-ptr; - prop = msi_alloc((len+1)*sizeof(WCHAR)); - memcpy(prop,ptr,len*sizeof(WCHAR)); - prop[len]=0; - - if (!preserve_case) - struprW(prop); + prop = msi_alloc( (len + 1) * sizeof(WCHAR) ); + memcpy( prop, ptr, len * sizeof(WCHAR) ); + prop[len] = 0; + if (!preserve_case) struprW( prop ); ptr2++; - - len = 0; - ptr = ptr2; - while (*ptr && (quote || (!quote && *ptr!=' '))) - { - if (*ptr == '"') - quote = !quote; - ptr++; - len++; - } - - if (*ptr2=='"') - { - ptr2++; - len -= 2; - } - val = msi_alloc((len+1)*sizeof(WCHAR)); - memcpy(val,ptr2,len*sizeof(WCHAR)); - val[len] = 0; + while (*ptr2 == ' ') ptr2++; - if (lstrlenW(prop) > 0) + quotes = 0; + val = msi_alloc( (strlenW( ptr2 ) + 1) * sizeof(WCHAR) ); + len = parse_prop( ptr2, val, "es ); + if (quotes % 2) { - UINT r = msi_set_property( package->db, prop, val ); - - TRACE("Found commandline property (%s) = (%s)\n", - debugstr_w(prop), debugstr_w(val)); - - if (r == ERROR_SUCCESS && !strcmpW( prop, cszSourceDir )) - msi_reset_folders( package, TRUE ); + WARN("unbalanced quotes\n"); + msi_free( val ); + msi_free( prop ); + return ERROR_INVALID_COMMAND_LINE; } - msi_free(val); - msi_free(prop); + remove_quotes( val ); + TRACE("Found commandline property %s = %s\n", debugstr_w(prop), debugstr_w(val)); + + r = msi_set_property( package->db, prop, val ); + if (r == ERROR_SUCCESS && !strcmpW( prop, cszSourceDir )) + msi_reset_folders( package, TRUE ); + + msi_free( val ); + msi_free( prop ); + + ptr = ptr2 + len; } return ERROR_SUCCESS; } - -static LPWSTR* msi_split_string( LPCWSTR str, WCHAR sep ) +WCHAR **msi_split_string( const WCHAR *str, WCHAR sep ) { LPCWSTR pc; LPWSTR p, *ret = NULL; @@ -445,7 +525,7 @@ UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ) guids = msi_split_string( guid_list, ';' ); for ( i = 0; guids[i] && ret != ERROR_SUCCESS; i++ ) { - if (!lstrcmpW( guids[i], product_code )) + if (!strcmpW( guids[i], product_code )) ret = ERROR_SUCCESS; } msi_free( guids ); @@ -679,7 +759,27 @@ static UINT msi_apply_transforms( MSIPACKAGE *package ) if (xforms[i][0] == ':') r = msi_apply_substorage_transform( package, package->db, xforms[i] ); else - r = MSI_DatabaseApplyTransformW( package->db, xforms[i], 0 ); + { + WCHAR *transform; + + if (!PathIsRelativeW( xforms[i] )) transform = xforms[i]; + else + { + WCHAR *p = strrchrW( package->PackagePath, '\\' ); + DWORD len = p - package->PackagePath + 1; + + if (!(transform = msi_alloc( (len + strlenW( xforms[i] ) + 1) * sizeof(WCHAR)) )) + { + msi_free( xforms ); + msi_free( xform_list ); + return ERROR_OUTOFMEMORY; + } + memcpy( transform, package->PackagePath, len * sizeof(WCHAR) ); + memcpy( transform + len, xforms[i], (strlenW( xforms[i] ) + 1) * sizeof(WCHAR) ); + } + r = MSI_DatabaseApplyTransformW( package->db, transform, 0 ); + if (transform != xforms[i]) msi_free( transform ); + } } msi_free( xforms ); @@ -964,6 +1064,9 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) MSICOMPONENT *comp; component = MSI_RecordGetString(row, 2); + if (!component) + return ERROR_SUCCESS; + comp = get_loaded_component(package, component); if (!comp) return ERROR_SUCCESS; @@ -994,7 +1097,7 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) ui_actiondata(package, szCreateFolders, uirow); msiobj_release(&uirow->hdr); - full_path = resolve_folder(package,dir,FALSE,FALSE,TRUE,&folder); + full_path = resolve_target_folder( package, dir, FALSE, TRUE, &folder ); if (!full_path) { ERR("Unable to resolve folder id %s\n",debugstr_w(dir)); @@ -1014,16 +1117,14 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) static UINT ACTION_CreateFolders(MSIPACKAGE *package) { - static const WCHAR ExecSeqQuery[] = - {'S','E','L','E','C','T',' ', - '`','D','i','r','e','c','t','o','r','y','_','`', - ' ','F','R','O','M',' ', - '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0 }; + static const WCHAR query[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0}; UINT rc; MSIQUERY *view; /* create all the empty folders specified in the CreateFolder table */ - rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view ); + rc = MSI_DatabaseOpenViewW(package->db, query, &view ); if (rc != ERROR_SUCCESS) return ERROR_SUCCESS; @@ -1043,6 +1144,9 @@ static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param ) MSICOMPONENT *comp; component = MSI_RecordGetString(row, 2); + if (!component) + return ERROR_SUCCESS; + comp = get_loaded_component(package, component); if (!comp) return ERROR_SUCCESS; @@ -1068,7 +1172,7 @@ static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param ) return ERROR_SUCCESS; } - full_path = resolve_folder( package, dir, FALSE, FALSE, TRUE, &folder ); + full_path = resolve_target_folder( package, dir, FALSE, TRUE, &folder ); if (!full_path) { ERR("Unable to resolve folder id %s\n", debugstr_w(dir)); @@ -1092,8 +1196,8 @@ static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param ) static UINT ACTION_RemoveFolders( MSIPACKAGE *package ) { static const WCHAR query[] = - {'S','E','L','E','C','T',' ', '`','D','i','r','e','c','t','o','r','y','_','`', - ' ','F','R','O','M',' ', '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0}; + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0}; MSIQUERY *view; UINT rc; @@ -1131,8 +1235,10 @@ static UINT load_component( MSIRECORD *row, LPVOID param ) comp->KeyPath = msi_dup_record_field( row, 6 ); comp->Installed = INSTALLSTATE_UNKNOWN; - msi_component_set_state(package, comp, INSTALLSTATE_UNKNOWN); + comp->Action = INSTALLSTATE_UNKNOWN; + comp->ActionRequest = INSTALLSTATE_UNKNOWN; + comp->assembly = load_assembly( package, comp ); return ERROR_SUCCESS; } @@ -1218,7 +1324,7 @@ static MSIFEATURE *find_feature_by_name( MSIPACKAGE *package, LPCWSTR name ) LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - if ( !lstrcmpW( feature->Feature, name ) ) + if ( !strcmpW( feature->Feature, name ) ) return feature; } @@ -1265,7 +1371,8 @@ static UINT load_feature(MSIRECORD * row, LPVOID param) feature->Attributes = MSI_RecordGetInteger(row,8); feature->Installed = INSTALLSTATE_UNKNOWN; - msi_feature_set_state(package, feature, INSTALLSTATE_UNKNOWN); + feature->Action = INSTALLSTATE_UNKNOWN; + feature->ActionRequest = INSTALLSTATE_UNKNOWN; list_add_tail( &package->features, &feature->entry ); @@ -1515,9 +1622,9 @@ static UINT load_folder( MSIRECORD *row, LPVOID param ) src_long = folder_split_path( src_short, '|' ); /* check for no-op dirs */ - if (!lstrcmpW(szDot, tgt_short)) + if (tgt_short && !strcmpW( szDot, tgt_short )) tgt_short = szEmpty; - if (!lstrcmpW(szDot, src_short)) + if (src_short && !strcmpW( szDot, src_short )) src_short = szEmpty; if (!tgt_long) @@ -1636,48 +1743,48 @@ static UINT ACTION_FileCost(MSIPACKAGE *package) static void ACTION_GetComponentInstallStates(MSIPACKAGE *package) { MSICOMPONENT *comp; - INSTALLSTATE state; UINT r; - state = MsiQueryProductStateW(package->ProductCode); - LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry) { - if (!comp->ComponentId) - continue; + if (!comp->ComponentId) continue; - if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT) + r = MsiQueryComponentStateW( package->ProductCode, NULL, + MSIINSTALLCONTEXT_USERMANAGED, comp->ComponentId, + &comp->Installed ); + if (r != ERROR_SUCCESS) + r = MsiQueryComponentStateW( package->ProductCode, NULL, + MSIINSTALLCONTEXT_USERUNMANAGED, comp->ComponentId, + &comp->Installed ); + if (r != ERROR_SUCCESS) + r = MsiQueryComponentStateW( package->ProductCode, NULL, + MSIINSTALLCONTEXT_MACHINE, comp->ComponentId, + &comp->Installed ); + if (r != ERROR_SUCCESS) comp->Installed = INSTALLSTATE_ABSENT; - else - { - r = MsiQueryComponentStateW(package->ProductCode, NULL, - package->Context, comp->ComponentId, - &comp->Installed); - if (r != ERROR_SUCCESS) - comp->Installed = INSTALLSTATE_ABSENT; - } } } static void ACTION_GetFeatureInstallStates(MSIPACKAGE *package) { MSIFEATURE *feature; - INSTALLSTATE state; - - state = MsiQueryProductStateW(package->ProductCode); LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT) + INSTALLSTATE state = MsiQueryFeatureStateW( package->ProductCode, feature->Feature ); + + if (state == INSTALLSTATE_UNKNOWN || state == INSTALLSTATE_INVALIDARG) feature->Installed = INSTALLSTATE_ABSENT; else - { - feature->Installed = MsiQueryFeatureStateW(package->ProductCode, - feature->Feature); - } + feature->Installed = state; } } +static inline BOOL is_feature_selected( MSIFEATURE *feature, INT level ) +{ + return (feature->Level > 0 && feature->Level <= level); +} + static BOOL process_state_property(MSIPACKAGE* package, int level, LPCWSTR property, INSTALLSTATE state) { @@ -1690,14 +1797,19 @@ static BOOL process_state_property(MSIPACKAGE* package, int level, LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - if (lstrcmpW(property, szRemove) && - (feature->Level <= 0 || feature->Level > level)) + if (strcmpW( property, szRemove ) && !is_feature_selected( feature, level )) continue; if (!strcmpW(property, szReinstall)) state = feature->Installed; - if (strcmpiW(override, szAll)==0) - msi_feature_set_state(package, feature, state); + if (!strcmpiW( override, szAll )) + { + if (feature->Installed != state) + { + feature->Action = state; + feature->ActionRequest = state; + } + } else { LPWSTR ptr = override; @@ -1710,7 +1822,11 @@ static BOOL process_state_property(MSIPACKAGE* package, int level, if ((ptr2 && strlenW(feature->Feature) == len && !strncmpW(ptr, feature->Feature, len)) || (!ptr2 && !strcmpW(ptr, feature->Feature))) { - msi_feature_set_state(package, feature, state); + if (feature->Installed != state) + { + feature->Action = state; + feature->ActionRequest = state; + } break; } if (ptr2) @@ -1724,7 +1840,6 @@ static BOOL process_state_property(MSIPACKAGE* package, int level, } } msi_free(override); - return TRUE; } @@ -1782,17 +1897,25 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) { LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - BOOL feature_state = ((feature->Level > 0) && - (feature->Level <= level)); + if (!is_feature_selected( feature, level )) continue; - if (feature_state && feature->ActionRequest == INSTALLSTATE_UNKNOWN) + if (feature->ActionRequest == INSTALLSTATE_UNKNOWN) { if (feature->Attributes & msidbFeatureAttributesFavorSource) - msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE); + { + feature->Action = INSTALLSTATE_SOURCE; + feature->ActionRequest = INSTALLSTATE_SOURCE; + } else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise) - msi_feature_set_state(package, feature, INSTALLSTATE_ADVERTISED); + { + feature->Action = INSTALLSTATE_ADVERTISED; + feature->ActionRequest = INSTALLSTATE_ADVERTISED; + } else - msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL); + { + feature->Action = INSTALLSTATE_LOCAL; + feature->ActionRequest = INSTALLSTATE_LOCAL; + } } } @@ -1801,29 +1924,38 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) { FeatureList *fl; - if (feature->Level > 0 && feature->Level <= level) - continue; + if (is_feature_selected( feature, level )) continue; LIST_FOR_EACH_ENTRY( fl, &feature->Children, FeatureList, entry ) - msi_feature_set_state(package, fl->feature, INSTALLSTATE_UNKNOWN); + { + fl->feature->Action = INSTALLSTATE_UNKNOWN; + fl->feature->ActionRequest = INSTALLSTATE_UNKNOWN; + } } } - else + else /* preselected */ { LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - BOOL selected = feature->Level > 0 && feature->Level <= level; + if (!is_feature_selected( feature, level )) continue; - if (selected && feature->ActionRequest == INSTALLSTATE_UNKNOWN) + if (feature->ActionRequest == INSTALLSTATE_UNKNOWN) { - msi_feature_set_state(package, feature, feature->Installed); + if (feature->Installed == INSTALLSTATE_ABSENT) + { + feature->Action = INSTALLSTATE_UNKNOWN; + feature->ActionRequest = INSTALLSTATE_UNKNOWN; + } + else + { + feature->Action = feature->Installed; + feature->ActionRequest = feature->Installed; + } } } } - /* - * now we want to enable or disable components based on feature - */ + /* now we want to set component state based based on feature state */ LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { ComponentList *cl; @@ -1832,8 +1964,7 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) debugstr_w(feature->Feature), feature->Level, feature->Installed, feature->ActionRequest, feature->Action); - if (!feature->Level) - continue; + if (!is_feature_selected( feature, level )) continue; /* features with components that have compressed files are made local */ LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) @@ -1841,7 +1972,8 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) if (cl->component->ForceLocalState && feature->ActionRequest == INSTALLSTATE_SOURCE) { - msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL); + feature->Action = INSTALLSTATE_LOCAL; + feature->ActionRequest = INSTALLSTATE_LOCAL; break; } } @@ -1886,34 +2018,44 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) { if ((component->Attributes & msidbComponentAttributesSourceOnly) && !component->ForceLocalState) - msi_component_set_state(package, component, INSTALLSTATE_SOURCE); + { + component->Action = INSTALLSTATE_SOURCE; + component->ActionRequest = INSTALLSTATE_SOURCE; + } else - msi_component_set_state(package, component, INSTALLSTATE_LOCAL); + { + component->Action = INSTALLSTATE_LOCAL; + component->ActionRequest = INSTALLSTATE_LOCAL; + } continue; } /* if any feature is local, the component must be local too */ if (component->hasLocalFeature) { - msi_component_set_state(package, component, INSTALLSTATE_LOCAL); + component->Action = INSTALLSTATE_LOCAL; + component->ActionRequest = INSTALLSTATE_LOCAL; continue; } - if (component->hasSourceFeature) { - msi_component_set_state(package, component, INSTALLSTATE_SOURCE); + component->Action = INSTALLSTATE_SOURCE; + component->ActionRequest = INSTALLSTATE_SOURCE; continue; } - if (component->hasAdvertiseFeature) { - msi_component_set_state(package, component, INSTALLSTATE_ADVERTISED); + component->Action = INSTALLSTATE_ADVERTISED; + component->ActionRequest = INSTALLSTATE_ADVERTISED; continue; } - TRACE("nobody wants component %s\n", debugstr_w(component->Component)); - if (component->anyAbsent) - msi_component_set_state(package, component, INSTALLSTATE_ABSENT); + if (component->anyAbsent && + (component->Installed == INSTALLSTATE_LOCAL || component->Installed == INSTALLSTATE_SOURCE)) + { + component->Action = INSTALLSTATE_ABSENT; + component->ActionRequest = INSTALLSTATE_ABSENT; + } } LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry ) @@ -1921,7 +2063,16 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) if (component->ActionRequest == INSTALLSTATE_DEFAULT) { TRACE("%s was default, setting to local\n", debugstr_w(component->Component)); - msi_component_set_state(package, component, INSTALLSTATE_LOCAL); + component->Action = INSTALLSTATE_LOCAL; + component->ActionRequest = INSTALLSTATE_LOCAL; + } + + if (component->ActionRequest == INSTALLSTATE_SOURCE && + component->Installed == INSTALLSTATE_SOURCE && + component->hasSourceFeature) + { + component->Action = INSTALLSTATE_UNKNOWN; + component->ActionRequest = INSTALLSTATE_UNKNOWN; } TRACE("Result: Component %s (Installed %d Request %d Action %d)\n", @@ -1947,10 +2098,9 @@ static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param) msi_free(f->ResolvedTarget); f->ResolvedTarget = NULL; - /* This helper function now does ALL the work */ - TRACE("Dir %s ...\n",debugstr_w(name)); - path = resolve_folder(package,name,FALSE,TRUE,TRUE,NULL); - TRACE("resolves to %s\n",debugstr_w(path)); + TRACE("directory %s ...\n", debugstr_w(name)); + path = resolve_target_folder( package, name, TRUE, TRUE, NULL ); + TRACE("resolves to %s\n", debugstr_w(path)); msi_free(path); return ERROR_SUCCESS; @@ -2028,7 +2178,19 @@ int msi_compare_file_versions( VS_FIXEDFILEINFO *fi, const WCHAR *version ) return 0; } -static DWORD get_disk_file_size( LPCWSTR filename ) +int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 ) +{ + DWORD ms1, ms2; + + msi_parse_version_string( ver1, &ms1, NULL ); + msi_parse_version_string( ver2, &ms2, NULL ); + + if (ms1 > ms2) return 1; + else if (ms1 < ms2) return -1; + return 0; +} + +DWORD msi_get_disk_file_size( LPCWSTR filename ) { HANDLE file; DWORD size; @@ -2044,7 +2206,7 @@ static DWORD get_disk_file_size( LPCWSTR filename ) return size; } -static BOOL hash_matches( MSIFILE *file ) +BOOL msi_file_hash_matches( MSIFILE *file ) { UINT r; MSIFILEHASHINFO hash; @@ -2057,77 +2219,95 @@ static BOOL hash_matches( MSIFILE *file ) return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) ); } -static UINT set_file_install_states( MSIPACKAGE *package ) +static WCHAR *get_temp_dir( void ) +{ + static UINT id; + WCHAR tmp[MAX_PATH], dir[MAX_PATH]; + + GetTempPathW( MAX_PATH, tmp ); + for (;;) + { + if (!GetTempFileNameW( tmp, szMsi, ++id, dir )) return NULL; + if (CreateDirectoryW( dir, NULL )) break; + } + return strdupW( dir ); +} + +static void set_target_path( MSIPACKAGE *package, MSIFILE *file ) +{ + MSIASSEMBLY *assembly = file->Component->assembly; + + TRACE("file %s is named %s\n", debugstr_w(file->File), debugstr_w(file->FileName)); + + msi_free( file->TargetPath ); + if (assembly && !assembly->application) + { + if (!assembly->tempdir) assembly->tempdir = get_temp_dir(); + file->TargetPath = build_directory_name( 2, assembly->tempdir, file->FileName ); + track_tempfile( package, file->TargetPath ); + } + else + { + WCHAR *dir = resolve_target_folder( package, file->Component->Directory, FALSE, TRUE, NULL ); + file->TargetPath = build_directory_name( 2, dir, file->FileName ); + msi_free( dir ); + } + + TRACE("resolves to %s\n", debugstr_w(file->TargetPath)); +} + +static UINT calculate_file_cost( MSIPACKAGE *package ) { VS_FIXEDFILEINFO *file_version; + WCHAR *font_version; MSIFILE *file; LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { - MSICOMPONENT* comp = file->Component; + MSICOMPONENT *comp = file->Component; DWORD file_size; - LPWSTR p; - if (!comp) - continue; + if (!comp->Enabled) continue; if (file->IsCompressed) comp->ForceLocalState = TRUE; - /* calculate target */ - p = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL); - msi_free(file->TargetPath); + set_target_path( package, file ); - TRACE("file %s is named %s\n", debugstr_w(file->File), debugstr_w(file->FileName)); - - file->TargetPath = build_directory_name(2, p, file->FileName); - msi_free(p); - - TRACE("file %s resolves to %s\n", debugstr_w(file->File), debugstr_w(file->TargetPath)); - - if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) + if ((comp->assembly && !comp->assembly->installed) || + GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) { - file->state = msifs_missing; comp->Cost += file->FileSize; continue; } - if (file->Version && (file_version = msi_get_disk_file_version( file->TargetPath ))) - { - TRACE("new %s old %u.%u.%u.%u\n", debugstr_w(file->Version), - HIWORD(file_version->dwFileVersionMS), - LOWORD(file_version->dwFileVersionMS), - HIWORD(file_version->dwFileVersionLS), - LOWORD(file_version->dwFileVersionLS)); + file_size = msi_get_disk_file_size( file->TargetPath ); - if (msi_compare_file_versions( file_version, file->Version ) < 0) - { - file->state = msifs_overwrite; - comp->Cost += file->FileSize; - } - else - { - TRACE("Destination file version equal or greater, not overwriting\n"); - file->state = msifs_present; - } - msi_free( file_version ); - continue; - } - if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize) + if (file->Version) + { + if ((file_version = msi_get_disk_file_version( file->TargetPath ))) + { + if (msi_compare_file_versions( file_version, file->Version ) < 0) + { + comp->Cost += file->FileSize - file_size; + } + msi_free( file_version ); + continue; + } + else if ((font_version = font_version_from_file( file->TargetPath ))) + { + if (msi_compare_font_versions( font_version, file->Version ) < 0) + { + comp->Cost += file->FileSize - file_size; + } + msi_free( font_version ); + continue; + } + } + if (file_size != file->FileSize) { - file->state = msifs_overwrite; comp->Cost += file->FileSize - file_size; - continue; } - if (file->hash.dwFileHashInfoSize && hash_matches( file )) - { - TRACE("File hashes match, not overwriting\n"); - file->state = msifs_present; - continue; - } - file->state = msifs_overwrite; - comp->Cost += file->FileSize - file_size; } - return ERROR_SUCCESS; } @@ -2166,13 +2346,22 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) msiobj_release(&view->hdr); } + TRACE("Evaluating component conditions\n"); + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + { + if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) + { + TRACE("Disabling component %s\n", debugstr_w(comp->Component)); + comp->Enabled = FALSE; + } + else + comp->Enabled = TRUE; + } + /* read components states from the registry */ ACTION_GetComponentInstallStates(package); ACTION_GetFeatureInstallStates(package); - TRACE("Calculating file install states\n"); - set_file_install_states( package ); - if (!process_overrides( package, msi_get_property_int( package->db, szlevel, 1 ) )) { TRACE("Evaluating feature conditions\n"); @@ -2184,18 +2373,9 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) msiobj_release( &view->hdr ); } } - TRACE("Evaluating component conditions\n"); - LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) - { - if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) - { - TRACE("Disabling component %s\n", debugstr_w(comp->Component)); - comp->Enabled = FALSE; - } - else - comp->Enabled = TRUE; - } + TRACE("Calculating file cost\n"); + calculate_file_cost( package ); msi_set_property( package->db, szCosting, szOne ); /* set default run level if not set */ @@ -2313,7 +2493,7 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, else ptr=value; - if (strstrW(value,szMulti)) + if (strstrW(value, szMulti)) *type = REG_MULTI_SZ; /* remove initial delimiter */ @@ -2467,6 +2647,7 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) { ERR("Could not create key %s\n", debugstr_w(keypath)); msi_free(uikey); + msi_free(keypath); return ERROR_SUCCESS; } @@ -2518,6 +2699,7 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) msi_free(value_data); msi_free(deformated); msi_free(uikey); + msi_free(keypath); return ERROR_SUCCESS; } @@ -2553,7 +2735,7 @@ static void delete_reg_key_or_value( HKEY hkey_root, LPCWSTR key, LPCWSTR value, { if ((res = RegDeleteTreeW( hkey_root, key ))) { - WARN("Failed to delete key %s (%d)\n", debugstr_w(key), res); + TRACE("Failed to delete key %s (%d)\n", debugstr_w(key), res); } return; } @@ -2562,12 +2744,11 @@ static void delete_reg_key_or_value( HKEY hkey_root, LPCWSTR key, LPCWSTR value, { if ((res = RegDeleteValueW( hkey, value ))) { - WARN("Failed to delete value %s (%d)\n", debugstr_w(value), res); + TRACE("Failed to delete value %s (%d)\n", debugstr_w(value), res); } res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, &num_values, NULL, NULL, NULL, NULL ); RegCloseKey( hkey ); - if (!res && !num_subkeys && !num_values) { TRACE("Removing empty key %s\n", debugstr_w(key)); @@ -2575,7 +2756,7 @@ static void delete_reg_key_or_value( HKEY hkey_root, LPCWSTR key, LPCWSTR value, } return; } - WARN("Failed to open key %s (%d)\n", debugstr_w(key), res); + TRACE("Failed to open key %s (%d)\n", debugstr_w(key), res); } @@ -2868,7 +3049,7 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp ) { if (!cmp->KeyPath) - return resolve_folder(package,cmp->Directory,FALSE,FALSE,TRUE,NULL); + return resolve_target_folder( package, cmp->Directory, FALSE, TRUE, NULL ); if (cmp->Attributes & msidbComponentAttributesRegistryKeyPath) { @@ -2970,9 +3151,6 @@ static UINT ACTION_WriteSharedDLLsCount(LPCWSTR path, UINT count) return count; } -/* - * Return TRUE if the count should be written out and FALSE if not - */ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp ) { MSIFEATURE *feature; @@ -2981,6 +3159,7 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp ) /* only refcount DLLs */ if (comp->KeyPath == NULL || + comp->assembly || comp->Attributes & msidbComponentAttributesRegistryKeyPath || comp->Attributes & msidbComponentAttributesODBCDataSource) write = FALSE; @@ -3071,7 +3250,19 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) squash_guid(comp->ComponentId,squished_cc); msi_free(comp->FullKeypath); - comp->FullKeypath = resolve_keypath( package, comp ); + if (comp->assembly) + { + const WCHAR prefixW[] = {'<','\\',0}; + DWORD len = strlenW( prefixW ) + strlenW( comp->assembly->display_name ); + + comp->FullKeypath = msi_alloc( (len + 1) * sizeof(WCHAR) ); + if (comp->FullKeypath) + { + strcpyW( comp->FullKeypath, prefixW ); + strcatW( comp->FullKeypath, comp->assembly->display_name ); + } + } + else comp->FullKeypath = resolve_keypath( package, comp ); ACTION_RefCountComponent( package, comp ); @@ -3085,15 +3276,10 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) if (comp->ActionRequest == INSTALLSTATE_LOCAL || comp->ActionRequest == INSTALLSTATE_SOURCE) { - if (!comp->FullKeypath) - continue; - if (package->Context == MSIINSTALLCONTEXT_MACHINE) - rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, szLocalSid, - &hkey, TRUE); + rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, szLocalSid, &hkey, TRUE); else - rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, NULL, - &hkey, TRUE); + rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, NULL, &hkey, TRUE); if (rc != ERROR_SUCCESS) continue; @@ -3127,8 +3313,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) '>','=',' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ', '`','D','i','s','k','I','d','`',0}; - file = get_loaded_file(package, comp->KeyPath); - if (!file) + if (!comp->KeyPath || !(file = get_loaded_file(package, comp->KeyPath))) continue; row = MSI_QueryGetRecord(package->db, query, file->Sequence); @@ -3260,10 +3445,11 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) } comp->Action = INSTALLSTATE_LOCAL; - file = get_loaded_file( package, comp->KeyPath ); - if (!file) + if (!comp->KeyPath || !(file = get_loaded_file( package, comp->KeyPath ))) + { + TRACE("component has no key path\n"); return ERROR_SUCCESS; - + } ui_actiondata( package, szRegisterTypeLibraries, row ); module = LoadLibraryExW( file->TargetPath, NULL, LOAD_LIBRARY_AS_DATAFILE ); @@ -3286,8 +3472,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) helpid = MSI_RecordGetString(row,6); - if (helpid) - help = resolve_folder(package,helpid,FALSE,FALSE,TRUE,NULL); + if (helpid) help = resolve_target_folder( package, helpid, FALSE, TRUE, NULL ); res = RegisterTypeLib(tl_struct.ptLib,tl_struct.path,help); msi_free(help); @@ -3421,7 +3606,7 @@ static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row ) LPWSTR link_folder, link_file, filename; directory = MSI_RecordGetString( row, 2 ); - link_folder = resolve_folder( package, directory, FALSE, FALSE, TRUE, NULL ); + link_folder = resolve_target_folder( package, directory, FALSE, TRUE, NULL ); /* may be needed because of a bug somewhere else */ create_full_pathW( link_folder ); @@ -3542,7 +3727,7 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) if (!MSI_RecordIsNull(row,12)) { LPCWSTR wkdir = MSI_RecordGetString(row, 12); - path = resolve_folder(package, wkdir, FALSE, FALSE, TRUE, NULL); + path = resolve_target_folder( package, wkdir, FALSE, TRUE, NULL ); if (path) IShellLinkW_SetWorkingDirectory(sl, path); msi_free(path); @@ -3752,7 +3937,7 @@ static UINT msi_publish_sourcelist(MSIPACKAGE *package, HKEY hkey) LIST_FOR_EACH_ENTRY(info, &package->sourcelist_info, MSISOURCELISTINFO, entry) { - if (!lstrcmpW(info->property, INSTALLPROPERTY_LASTUSEDSOURCEW)) + if (!strcmpW( info->property, INSTALLPROPERTY_LASTUSEDSOURCEW )) msi_set_last_used_source(package->ProductCode, NULL, info->context, info->options, info->value); else @@ -4075,7 +4260,7 @@ static WCHAR *get_ini_file_name( MSIPACKAGE *package, MSIRECORD *row ) dirprop = MSI_RecordGetString( row, 3 ); if (dirprop) { - folder = resolve_folder( package, dirprop, FALSE, FALSE, TRUE, NULL ); + folder = resolve_target_folder( package, dirprop, FALSE, TRUE, NULL ); if (!folder) folder = msi_dup_property( package->db, dirprop ); } @@ -4855,7 +5040,7 @@ static UINT msi_unpublish_product(MSIPACKAGE *package, WCHAR *remove) return ERROR_FUNCTION_FAILED; } - if (!lstrcmpW(features[0], szAll)) + if (!strcmpW( features[0], szAll )) full_uninstall = TRUE; else { @@ -4874,21 +5059,16 @@ static UINT msi_unpublish_product(MSIPACKAGE *package, WCHAR *remove) MSIREG_DeleteUserDataProductKey(package->ProductCode); MSIREG_DeleteUninstallKey(package); - if (package->Context == MSIINSTALLCONTEXT_MACHINE) - { - MSIREG_DeleteLocalClassesProductKey(package->ProductCode); - MSIREG_DeleteLocalClassesFeaturesKey(package->ProductCode); - } - else - { - MSIREG_DeleteUserProductKey(package->ProductCode); - MSIREG_DeleteUserFeaturesKey(package->ProductCode); - } + MSIREG_DeleteLocalClassesProductKey(package->ProductCode); + MSIREG_DeleteLocalClassesFeaturesKey(package->ProductCode); + MSIREG_DeleteUserProductKey(package->ProductCode); + MSIREG_DeleteUserFeaturesKey(package->ProductCode); upgrade = msi_dup_property(package->db, szUpgradeCode); if (upgrade) { MSIREG_DeleteUserUpgradeCodesKey(upgrade); + MSIREG_DeleteClassesUpgradeCodesKey(upgrade); msi_free(upgrade); } @@ -5100,13 +5280,14 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param) { MSIPACKAGE *package = param; LPCWSTR compgroupid, component, feature, qualifier, text; - LPWSTR advertise = NULL, output = NULL; + LPWSTR advertise = NULL, output = NULL, existing = NULL, p, q; HKEY hkey = NULL; UINT rc; MSICOMPONENT *comp; MSIFEATURE *feat; DWORD sz; MSIRECORD *uirow; + int len; feature = MSI_RecordGetString(rec, 5); feat = get_loaded_feature(package, feature); @@ -5133,30 +5314,56 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param) rc = MSIREG_OpenUserComponentsKey(compgroupid, &hkey, TRUE); if (rc != ERROR_SUCCESS) goto end; - - text = MSI_RecordGetString(rec,4); - advertise = create_component_advertise_string(package, comp, feature); - - sz = strlenW(advertise); + advertise = create_component_advertise_string( package, comp, feature ); + text = MSI_RecordGetString( rec, 4 ); if (text) - sz += lstrlenW(text); + { + p = msi_alloc( (strlenW( advertise ) + strlenW( text ) + 1) * sizeof(WCHAR) ); + strcpyW( p, advertise ); + strcatW( p, text ); + msi_free( advertise ); + advertise = p; + } + existing = msi_reg_get_val_str( hkey, qualifier ); - sz+=3; - sz *= sizeof(WCHAR); - - output = msi_alloc_zero(sz); - strcpyW(output,advertise); - msi_free(advertise); - - if (text) - strcatW(output,text); + sz = strlenW( advertise ) + 1; + if (existing) + { + for (p = existing; *p; p += len) + { + len = strlenW( p ) + 1; + if (strcmpW( advertise, p )) sz += len; + } + } + if (!(output = msi_alloc( (sz + 1) * sizeof(WCHAR) ))) + { + rc = ERROR_OUTOFMEMORY; + goto end; + } + q = output; + if (existing) + { + for (p = existing; *p; p += len) + { + len = strlenW( p ) + 1; + if (strcmpW( advertise, p )) + { + memcpy( q, p, len * sizeof(WCHAR) ); + q += len; + } + } + } + strcpyW( q, advertise ); + q[strlenW( q ) + 1] = 0; msi_reg_set_val_multi_str( hkey, qualifier, output ); end: RegCloseKey(hkey); - msi_free(output); + msi_free( output ); + msi_free( advertise ); + msi_free( existing ); /* the UI chunk */ uirow = MSI_CreateRecord( 2 ); @@ -5272,11 +5479,11 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) MSIRECORD *row; MSIFILE *file; SC_HANDLE hscm, service = NULL; - LPCWSTR comp, depends, pass; - LPWSTR name = NULL, disp = NULL; - LPCWSTR load_order, serv_name, key; - DWORD serv_type, start_type; - DWORD err_control; + LPCWSTR comp, key; + LPWSTR name = NULL, disp = NULL, load_order = NULL, serv_name = NULL; + LPWSTR depends = NULL, pass = NULL, args = NULL, image_path = NULL; + DWORD serv_type, start_type, err_control; + SERVICE_DESCRIPTIONW sd = {NULL}; static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ', @@ -5292,22 +5499,24 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) goto done; } + comp = MSI_RecordGetString( rec, 12 ); + if (!get_loaded_component( package, comp )) + goto done; + start_type = MSI_RecordGetInteger(rec, 5); if (start_type == SERVICE_BOOT_START || start_type == SERVICE_SYSTEM_START) goto done; - depends = MSI_RecordGetString(rec, 8); - if (depends && *depends) - FIXME("Dependency list unhandled!\n"); - deformat_string(package, MSI_RecordGetString(rec, 2), &name); deformat_string(package, MSI_RecordGetString(rec, 3), &disp); serv_type = MSI_RecordGetInteger(rec, 4); err_control = MSI_RecordGetInteger(rec, 6); - load_order = MSI_RecordGetString(rec, 7); - serv_name = MSI_RecordGetString(rec, 9); - pass = MSI_RecordGetString(rec, 10); - comp = MSI_RecordGetString(rec, 12); + deformat_string(package, MSI_RecordGetString(rec, 7), &load_order); + deformat_string(package, MSI_RecordGetString(rec, 8), &depends); + deformat_string(package, MSI_RecordGetString(rec, 9), &serv_name); + deformat_string(package, MSI_RecordGetString(rec, 10), &pass); + deformat_string(package, MSI_RecordGetString(rec, 11), &args); + deformat_string(package, MSI_RecordGetString(rec, 13), &sd.lpDescription); /* fetch the service path */ row = MSI_QueryGetRecord(package->db, query, comp); @@ -5316,7 +5525,6 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) ERR("Control query failed!\n"); goto done; } - key = MSI_RecordGetString(row, 6); file = get_loaded_file(package, key); @@ -5327,20 +5535,44 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) goto done; } + if (!args || !args[0]) image_path = file->TargetPath; + else + { + int len = strlenW(file->TargetPath) + strlenW(args) + 2; + if (!(image_path = msi_alloc(len * sizeof(WCHAR)))) + return ERROR_OUTOFMEMORY; + + strcpyW(image_path, file->TargetPath); + strcatW(image_path, szSpace); + strcatW(image_path, args); + } service = CreateServiceW(hscm, name, disp, GENERIC_ALL, serv_type, - start_type, err_control, file->TargetPath, - load_order, NULL, NULL, serv_name, pass); + start_type, err_control, image_path, load_order, + NULL, depends, serv_name, pass); + if (!service) { if (GetLastError() != ERROR_SERVICE_EXISTS) ERR("Failed to create service %s: %d\n", debugstr_w(name), GetLastError()); } + else if (sd.lpDescription) + { + if (!ChangeServiceConfig2W(service, SERVICE_CONFIG_DESCRIPTION, &sd)) + WARN("failed to set service description %u\n", GetLastError()); + } + if (image_path != file->TargetPath) msi_free(image_path); done: CloseServiceHandle(service); CloseServiceHandle(hscm); msi_free(name); msi_free(disp); + msi_free(sd.lpDescription); + msi_free(load_order); + msi_free(serv_name); + msi_free(pass); + msi_free(depends); + msi_free(args); return ERROR_SUCCESS; } @@ -5780,27 +6012,15 @@ static UINT ACTION_DeleteServices( MSIPACKAGE *package ) return rc; } -static MSIFILE *msi_find_file( MSIPACKAGE *package, LPCWSTR filename ) -{ - MSIFILE *file; - - LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry) - { - if (!lstrcmpW(file->File, filename)) - return file; - } - - return NULL; -} - static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; LPWSTR driver, driver_path, ptr; WCHAR outpath[MAX_PATH]; - MSIFILE *driver_file, *setup_file; + MSIFILE *driver_file = NULL, *setup_file = NULL; + MSICOMPONENT *comp; MSIRECORD *uirow; - LPCWSTR desc; + LPCWSTR desc, file_key, component; DWORD len, usage; UINT r = ERROR_SUCCESS; @@ -5811,10 +6031,24 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param ) static const WCHAR usage_fmt[] = { 'F','i','l','e','U','s','a','g','e','=','1',0}; + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } + desc = MSI_RecordGetString(rec, 3); - driver_file = msi_find_file(package, MSI_RecordGetString(rec, 4)); - setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5)); + file_key = MSI_RecordGetString( rec, 4 ); + if (file_key) driver_file = get_loaded_file( package, file_key ); + + file_key = MSI_RecordGetString( rec, 5 ); + if (file_key) setup_file = get_loaded_file( package, file_key ); if (!driver_file) { @@ -5877,9 +6111,10 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param ) MSIPACKAGE *package = param; LPWSTR translator, translator_path, ptr; WCHAR outpath[MAX_PATH]; - MSIFILE *translator_file, *setup_file; + MSIFILE *translator_file = NULL, *setup_file = NULL; + MSICOMPONENT *comp; MSIRECORD *uirow; - LPCWSTR desc; + LPCWSTR desc, file_key, component; DWORD len, usage; UINT r = ERROR_SUCCESS; @@ -5888,10 +6123,24 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param ) static const WCHAR setup_fmt[] = { 'S','e','t','u','p','=','%','s',0}; + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } + desc = MSI_RecordGetString(rec, 3); - translator_file = msi_find_file(package, MSI_RecordGetString(rec, 4)); - setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5)); + file_key = MSI_RecordGetString( rec, 4 ); + if (file_key) translator_file = get_loaded_file( package, file_key ); + + file_key = MSI_RecordGetString( rec, 5 ); + if (file_key) setup_file = get_loaded_file( package, file_key ); if (!translator_file) { @@ -5948,8 +6197,9 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param ) static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; + MSICOMPONENT *comp; LPWSTR attrs; - LPCWSTR desc, driver; + LPCWSTR desc, driver, component; WORD request = ODBC_ADD_SYS_DSN; INT registration; DWORD len; @@ -5959,6 +6209,17 @@ static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param ) static const WCHAR attrs_fmt[] = { 'D','S','N','=','%','s',0 }; + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } + desc = MSI_RecordGetString(rec, 3); driver = MSI_RecordGetString(rec, 4); registration = MSI_RecordGetInteger(rec, 5); @@ -6036,9 +6297,21 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package ) static UINT ITERATE_RemoveODBCDriver( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; + MSICOMPONENT *comp; MSIRECORD *uirow; DWORD usage; - LPCWSTR desc; + LPCWSTR desc, component; + + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } desc = MSI_RecordGetString( rec, 3 ); if (!SQLRemoveDriverW( desc, FALSE, &usage )) @@ -6062,9 +6335,21 @@ static UINT ITERATE_RemoveODBCDriver( MSIRECORD *rec, LPVOID param ) static UINT ITERATE_RemoveODBCTranslator( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; + MSICOMPONENT *comp; MSIRECORD *uirow; DWORD usage; - LPCWSTR desc; + LPCWSTR desc, component; + + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } desc = MSI_RecordGetString( rec, 3 ); if (!SQLRemoveTranslatorW( desc, &usage )) @@ -6088,9 +6373,10 @@ static UINT ITERATE_RemoveODBCTranslator( MSIRECORD *rec, LPVOID param ) static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; + MSICOMPONENT *comp; MSIRECORD *uirow; LPWSTR attrs; - LPCWSTR desc, driver; + LPCWSTR desc, driver, component; WORD request = ODBC_REMOVE_SYS_DSN; INT registration; DWORD len; @@ -6098,6 +6384,17 @@ static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param ) static const WCHAR attrs_fmt[] = { 'D','S','N','=','%','s',0 }; + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } + desc = MSI_RecordGetString( rec, 3 ); driver = MSI_RecordGetString( rec, 4 ); registration = MSI_RecordGetInteger( rec, 5 ); @@ -6235,7 +6532,7 @@ static UINT env_parse_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags ) else if (lstrlenW(*value) >= prefix_len) { ptr += lstrlenW(ptr) - prefix_len; - if (!lstrcmpW(ptr, prefix)) + if (!strcmpW( ptr, prefix )) { if ((ptr-1) > *value && *(ptr-1) == szSemiColon[0]) { @@ -6406,7 +6703,7 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param ) if (res != ERROR_SUCCESS) goto done; - if (flags & ENV_ACT_REMOVEMATCH && (!value || !lstrcmpW(data, value))) + if (flags & ENV_ACT_REMOVEMATCH && (!value || !strcmpW( data, value ))) { action = 0x4; res = RegDeleteValueW(env, name); @@ -6590,481 +6887,6 @@ static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package ) return rc; } -typedef struct tagMSIASSEMBLY -{ - struct list entry; - MSICOMPONENT *component; - MSIFEATURE *feature; - MSIFILE *file; - LPWSTR manifest; - LPWSTR application; - LPWSTR display_name; - DWORD attributes; - BOOL installed; -} MSIASSEMBLY; - -static HRESULT (WINAPI *pCreateAssemblyCache)(IAssemblyCache **ppAsmCache, - DWORD dwReserved); -static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion, - LPVOID pvReserved, HMODULE *phModDll); - -static BOOL init_functionpointers(void) -{ - HRESULT hr; - HMODULE hfusion; - HMODULE hmscoree; - - static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0}; - - hmscoree = LoadLibraryA("mscoree.dll"); - if (!hmscoree) - { - WARN("mscoree.dll not available\n"); - return FALSE; - } - - pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim"); - if (!pLoadLibraryShim) - { - WARN("LoadLibraryShim not available\n"); - FreeLibrary(hmscoree); - return FALSE; - } - - hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion); - if (FAILED(hr)) - { - WARN("fusion.dll not available\n"); - FreeLibrary(hmscoree); - return FALSE; - } - - pCreateAssemblyCache = (void *)GetProcAddress(hfusion, "CreateAssemblyCache"); - - FreeLibrary(hmscoree); - return TRUE; -} - -static UINT install_assembly(MSIPACKAGE *package, MSIASSEMBLY *assembly, - LPWSTR path) -{ - IAssemblyCache *cache; - MSIRECORD *uirow; - HRESULT hr; - UINT r = ERROR_FUNCTION_FAILED; - - TRACE("installing assembly: %s\n", debugstr_w(path)); - - uirow = MSI_CreateRecord( 2 ); - MSI_RecordSetStringW( uirow, 2, assembly->display_name ); - ui_actiondata( package, szMsiPublishAssemblies, uirow ); - msiobj_release( &uirow->hdr ); - - if (assembly->feature) - msi_feature_set_state(package, assembly->feature, INSTALLSTATE_LOCAL); - - if (assembly->manifest) - FIXME("Manifest unhandled\n"); - - if (assembly->application) - { - FIXME("Assembly should be privately installed\n"); - return ERROR_SUCCESS; - } - - if (assembly->attributes == msidbAssemblyAttributesWin32) - { - FIXME("Win32 assemblies not handled\n"); - return ERROR_SUCCESS; - } - - hr = pCreateAssemblyCache(&cache, 0); - if (FAILED(hr)) - goto done; - - hr = IAssemblyCache_InstallAssembly(cache, 0, path, NULL); - if (FAILED(hr)) - ERR("Failed to install assembly: %s %08x\n", debugstr_w(path), hr); - - r = ERROR_SUCCESS; - -done: - IAssemblyCache_Release(cache); - return r; -} - -typedef struct tagASSEMBLY_LIST -{ - MSIPACKAGE *package; - IAssemblyCache *cache; - struct list *assemblies; -} ASSEMBLY_LIST; - -typedef struct tagASSEMBLY_NAME -{ - LPWSTR name; - LPWSTR version; - LPWSTR culture; - LPWSTR pubkeytoken; -} ASSEMBLY_NAME; - -static UINT parse_assembly_name(MSIRECORD *rec, LPVOID param) -{ - ASSEMBLY_NAME *asmname = param; - LPCWSTR name = MSI_RecordGetString(rec, 2); - LPWSTR val = msi_dup_record_field(rec, 3); - - static const WCHAR Name[] = {'N','a','m','e',0}; - static const WCHAR Version[] = {'V','e','r','s','i','o','n',0}; - static const WCHAR Culture[] = {'C','u','l','t','u','r','e',0}; - static const WCHAR PublicKeyToken[] = { - 'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0}; - - if (!strcmpiW(name, Name)) - asmname->name = val; - else if (!strcmpiW(name, Version)) - asmname->version = val; - else if (!strcmpiW(name, Culture)) - asmname->culture = val; - else if (!strcmpiW(name, PublicKeyToken)) - asmname->pubkeytoken = val; - else - msi_free(val); - - return ERROR_SUCCESS; -} - -static void append_str(LPWSTR *str, DWORD *size, LPCWSTR append) -{ - if (!*str) - { - *size = lstrlenW(append) + 1; - *str = msi_alloc((*size) * sizeof(WCHAR)); - lstrcpyW(*str, append); - return; - } - - (*size) += lstrlenW(append); - *str = msi_realloc(*str, (*size) * sizeof(WCHAR)); - lstrcatW(*str, append); -} - -static WCHAR *get_assembly_display_name( MSIDATABASE *db, MSICOMPONENT *comp ) -{ - static const WCHAR separator[] = {',',' ',0}; - static const WCHAR Version[] = {'V','e','r','s','i','o','n','=',0}; - static const WCHAR Culture[] = {'C','u','l','t','u','r','e','=',0}; - static const WCHAR PublicKeyToken[] = {'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0}; - static const WCHAR query[] = { - 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - '`','M','s','i','A','s','s','e','m','b','l','y','N','a','m','e','`',' ', - 'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`', - '=','\'','%','s','\'',0}; - ASSEMBLY_NAME name; - MSIQUERY *view; - LPWSTR display_name; - DWORD size; - UINT r; - - display_name = NULL; - memset( &name, 0, sizeof(ASSEMBLY_NAME) ); - - r = MSI_OpenQuery( db, &view, query, comp->Component ); - if (r != ERROR_SUCCESS) - return NULL; - - MSI_IterateRecords( view, NULL, parse_assembly_name, &name ); - msiobj_release( &view->hdr ); - - if (!name.name) - { - ERR("No assembly name specified!\n"); - return NULL; - } - - append_str( &display_name, &size, name.name ); - - if (name.version) - { - append_str( &display_name, &size, separator ); - append_str( &display_name, &size, Version ); - append_str( &display_name, &size, name.version ); - } - if (name.culture) - { - append_str( &display_name, &size, separator ); - append_str( &display_name, &size, Culture ); - append_str( &display_name, &size, name.culture ); - } - if (name.pubkeytoken) - { - append_str( &display_name, &size, separator ); - append_str( &display_name, &size, PublicKeyToken ); - append_str( &display_name, &size, name.pubkeytoken ); - } - - msi_free( name.name ); - msi_free( name.version ); - msi_free( name.culture ); - msi_free( name.pubkeytoken ); - - return display_name; -} - -static BOOL check_assembly_installed( MSIDATABASE *db, IAssemblyCache *cache, MSICOMPONENT *comp ) -{ - ASSEMBLY_INFO asminfo; - LPWSTR disp; - BOOL found = FALSE; - HRESULT hr; - - disp = get_assembly_display_name( db, comp ); - if (!disp) - return FALSE; - - memset( &asminfo, 0, sizeof(ASSEMBLY_INFO) ); - asminfo.cbAssemblyInfo = sizeof(ASSEMBLY_INFO); - - hr = IAssemblyCache_QueryAssemblyInfo( cache, QUERYASMINFO_FLAG_VALIDATE, disp, &asminfo ); - if (SUCCEEDED(hr)) - found = (asminfo.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED); - - msi_free( disp ); - return found; -} - -static UINT load_assembly(MSIRECORD *rec, LPVOID param) -{ - ASSEMBLY_LIST *list = param; - MSIASSEMBLY *assembly; - LPCWSTR component; - - assembly = msi_alloc_zero(sizeof(MSIASSEMBLY)); - if (!assembly) - return ERROR_OUTOFMEMORY; - - component = MSI_RecordGetString(rec, 1); - assembly->component = get_loaded_component(list->package, component); - if (!assembly->component) - return ERROR_SUCCESS; - - if (assembly->component->ActionRequest != INSTALLSTATE_LOCAL && - assembly->component->ActionRequest != INSTALLSTATE_SOURCE) - { - TRACE("Component not scheduled for installation: %s\n", debugstr_w(component)); - assembly->component->Action = assembly->component->Installed; - return ERROR_SUCCESS; - } - assembly->component->Action = assembly->component->ActionRequest; - - assembly->feature = find_feature_by_name(list->package, MSI_RecordGetString(rec, 2)); - assembly->file = msi_find_file(list->package, assembly->component->KeyPath); - - if (!assembly->file) - { - ERR("File %s not found\n", debugstr_w(assembly->component->KeyPath)); - return ERROR_FUNCTION_FAILED; - } - - assembly->manifest = strdupW(MSI_RecordGetString(rec, 3)); - assembly->application = strdupW(MSI_RecordGetString(rec, 4)); - assembly->attributes = MSI_RecordGetInteger(rec, 5); - - if (assembly->application) - { - WCHAR version[24]; - DWORD size = sizeof(version)/sizeof(WCHAR); - - /* FIXME: we should probably check the manifest file here */ - - if (!MsiGetFileVersionW(assembly->file->TargetPath, version, &size, NULL, NULL) && - (!assembly->file->Version || strcmpW(version, assembly->file->Version) >= 0)) - { - assembly->installed = TRUE; - } - } - else - assembly->installed = check_assembly_installed(list->package->db, - list->cache, - assembly->component); - - list_add_head(list->assemblies, &assembly->entry); - return ERROR_SUCCESS; -} - -static UINT load_assemblies(MSIPACKAGE *package, struct list *assemblies) -{ - IAssemblyCache *cache = NULL; - ASSEMBLY_LIST list; - MSIQUERY *view; - HRESULT hr; - UINT r; - - static const WCHAR query[] = - {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - '`','M','s','i','A','s','s','e','m','b','l','y','`',0}; - - r = MSI_DatabaseOpenViewW(package->db, query, &view); - if (r != ERROR_SUCCESS) - return ERROR_SUCCESS; - - hr = pCreateAssemblyCache(&cache, 0); - if (FAILED(hr)) - return ERROR_FUNCTION_FAILED; - - list.package = package; - list.cache = cache; - list.assemblies = assemblies; - - r = MSI_IterateRecords(view, NULL, load_assembly, &list); - msiobj_release(&view->hdr); - - IAssemblyCache_Release(cache); - - return r; -} - -static void free_assemblies(struct list *assemblies) -{ - struct list *item, *cursor; - - LIST_FOR_EACH_SAFE(item, cursor, assemblies) - { - MSIASSEMBLY *assembly = LIST_ENTRY(item, MSIASSEMBLY, entry); - - list_remove(&assembly->entry); - msi_free(assembly->application); - msi_free(assembly->manifest); - msi_free(assembly->display_name); - msi_free(assembly); - } -} - -static BOOL find_assembly(struct list *assemblies, LPCWSTR file, MSIASSEMBLY **out) -{ - MSIASSEMBLY *assembly; - - LIST_FOR_EACH_ENTRY(assembly, assemblies, MSIASSEMBLY, entry) - { - if (!lstrcmpW(assembly->file->File, file)) - { - *out = assembly; - return TRUE; - } - } - - return FALSE; -} - -static BOOL installassembly_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, - LPWSTR *path, DWORD *attrs, PVOID user) -{ - MSIASSEMBLY *assembly; - WCHAR temppath[MAX_PATH]; - struct list *assemblies = user; - UINT r; - - if (!find_assembly(assemblies, file, &assembly)) - return FALSE; - - GetTempPathW(MAX_PATH, temppath); - PathAddBackslashW(temppath); - lstrcatW(temppath, assembly->file->FileName); - - if (action == MSICABEXTRACT_BEGINEXTRACT) - { - if (assembly->installed) - return FALSE; - - *path = strdupW(temppath); - *attrs = assembly->file->Attributes; - } - else if (action == MSICABEXTRACT_FILEEXTRACTED) - { - assembly->installed = TRUE; - - r = install_assembly(package, assembly, temppath); - if (r != ERROR_SUCCESS) - ERR("Failed to install assembly\n"); - } - - return TRUE; -} - -static UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package ) -{ - UINT r; - struct list assemblies = LIST_INIT(assemblies); - MSIASSEMBLY *assembly; - MSIMEDIAINFO *mi; - - if (!init_functionpointers() || !pCreateAssemblyCache) - return ERROR_FUNCTION_FAILED; - - r = load_assemblies(package, &assemblies); - if (r != ERROR_SUCCESS) - goto done; - - if (list_empty(&assemblies)) - goto done; - - mi = msi_alloc_zero(sizeof(MSIMEDIAINFO)); - if (!mi) - { - r = ERROR_OUTOFMEMORY; - goto done; - } - - LIST_FOR_EACH_ENTRY(assembly, &assemblies, MSIASSEMBLY, entry) - { - if (assembly->installed && !mi->is_continuous) - continue; - - if (assembly->file->IsCompressed) - { - if (assembly->file->disk_id != mi->disk_id || mi->is_continuous) - { - MSICABDATA data; - - r = ready_media(package, assembly->file, mi); - if (r != ERROR_SUCCESS) - { - ERR("Failed to ready media\n"); - break; - } - - data.mi = mi; - data.package = package; - data.cb = installassembly_cb; - data.user = &assemblies; - - if (!msi_cabextract(package, mi, &data)) - { - ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet)); - r = ERROR_FUNCTION_FAILED; - break; - } - } - } - else - { - LPWSTR source = resolve_file_source(package, assembly->file); - - r = install_assembly(package, assembly, source); - if (r != ERROR_SUCCESS) - ERR("Failed to install assembly\n"); - - msi_free(source); - } - - /* FIXME: write Installer assembly reg values */ - } - -done: - free_assemblies(&assemblies); - return r; -} - static UINT ACTION_ValidateProductID( MSIPACKAGE *package ) { LPWSTR key, template, id; @@ -7159,6 +6981,101 @@ static UINT ACTION_SetODBCFolders( MSIPACKAGE *package ) return ERROR_SUCCESS; } +static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param ) +{ + MSIPACKAGE *package = param; + const WCHAR *property = MSI_RecordGetString( rec, 1 ); + WCHAR *value; + + if ((value = msi_dup_property( package->db, property ))) + { + FIXME("remove %s\n", debugstr_w(value)); + msi_free( value ); + } + return ERROR_SUCCESS; +} + +static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package ) +{ + UINT r; + MSIQUERY *view; + + static const WCHAR query[] = + {'S','E','L','E','C','T',' ','A','c','t','i','o','n','P','r','o','p','e','r','t','y', + ' ','F','R','O','M',' ','U','p','g','r','a','d','e',0}; + + r = MSI_DatabaseOpenViewW( package->db, query, &view ); + if (r == ERROR_SUCCESS) + { + r = MSI_IterateRecords( view, NULL, ITERATE_RemoveExistingProducts, package ); + msiobj_release( &view->hdr ); + } + return ERROR_SUCCESS; +} + +static UINT ITERATE_MigrateFeatureStates( MSIRECORD *rec, LPVOID param ) +{ + MSIPACKAGE *package = param; + int attributes = MSI_RecordGetInteger( rec, 5 ); + + if (attributes & msidbUpgradeAttributesMigrateFeatures) + { + const WCHAR *upgrade_code = MSI_RecordGetString( rec, 1 ); + const WCHAR *version_min = MSI_RecordGetString( rec, 2 ); + const WCHAR *version_max = MSI_RecordGetString( rec, 3 ); + const WCHAR *language = MSI_RecordGetString( rec, 4 ); + HKEY hkey; + UINT r; + + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + { + r = MSIREG_OpenClassesUpgradeCodesKey( upgrade_code, &hkey, FALSE ); + if (r != ERROR_SUCCESS) + return ERROR_SUCCESS; + } + else + { + r = MSIREG_OpenUserUpgradeCodesKey( upgrade_code, &hkey, FALSE ); + if (r != ERROR_SUCCESS) + return ERROR_SUCCESS; + } + RegCloseKey( hkey ); + + FIXME("migrate feature states from %s version min %s version max %s language %s\n", + debugstr_w(upgrade_code), debugstr_w(version_min), + debugstr_w(version_max), debugstr_w(language)); + } + return ERROR_SUCCESS; +} + +static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package ) +{ + UINT r; + MSIQUERY *view; + + static const WCHAR query[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','U','p','g','r','a','d','e',0}; + + if (msi_get_property_int( package->db, szInstalled, 0 )) + { + TRACE("product is installed, skipping action\n"); + return ERROR_SUCCESS; + } + if (msi_get_property_int( package->db, szPreselected, 0 )) + { + TRACE("Preselected property is set, not migrating feature states\n"); + return ERROR_SUCCESS; + } + + r = MSI_DatabaseOpenViewW( package->db, query, &view ); + if (r == ERROR_SUCCESS) + { + r = MSI_IterateRecords( view, NULL, ITERATE_MigrateFeatureStates, package ); + msiobj_release( &view->hdr ); + } + return ERROR_SUCCESS; +} + static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, LPCWSTR table ) { @@ -7202,19 +7119,6 @@ static UINT ACTION_IsolateComponents( MSIPACKAGE *package ) return msi_unimplemented_action_stub( package, "IsolateComponents", table ); } -static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'U','p','g','r','a','d','e',0 }; - return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table ); -} - -static UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { - 'M','s','i','A','s','s','e','m','b','l','y',0 }; - return msi_unimplemented_action_stub( package, "MsiUnpublishAssemblies", table ); -} - static UINT ACTION_RMCCPSearch( MSIPACKAGE *package ) { static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 }; @@ -7239,12 +7143,6 @@ static UINT ACTION_InstallSFPCatalogFile( MSIPACKAGE *package ) return msi_unimplemented_action_stub( package, "InstallSFPCatalogFile", table ); } -static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'U','p','g','r','a','d','e',0 }; - return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table ); -} - typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*); static const struct @@ -7516,7 +7414,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, msi_set_sourcedir_props(package, FALSE); } - msi_parse_command_line( package, szCommandLine, FALSE ); + rc = msi_parse_command_line( package, szCommandLine, FALSE ); + if (rc != ERROR_SUCCESS) + return rc; msi_apply_transforms( package ); msi_apply_patches( package ); diff --git a/reactos/dll/win32/msi/appsearch.c b/reactos/dll/win32/msi/appsearch.c index dfab3960b01..c8aea77fd35 100644 --- a/reactos/dll/win32/msi/appsearch.c +++ b/reactos/dll/win32/msi/appsearch.c @@ -71,7 +71,7 @@ void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls) x4 = atoiW(ptr + 1); /* FIXME: byte-order dependent? */ *ms = x1 << 16 | x2; - *ls = x3 << 16 | x4; + if (ls) *ls = x3 << 16 | x4; } /* Fills in sig with the values from the Signature table, where name is the @@ -796,8 +796,8 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, if (hFind != INVALID_HANDLE_VALUE) { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && - lstrcmpW(findData.cFileName, szDot) && - lstrcmpW(findData.cFileName, szDotDot)) + strcmpW( findData.cFileName, szDot ) && + strcmpW( findData.cFileName, szDotDot )) { lstrcpyW(subpath, dir); PathAppendW(subpath, findData.cFileName); @@ -808,8 +808,8 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, while (rc == ERROR_SUCCESS && !*appValue && FindNextFileW(hFind, &findData) != 0) { - if (!lstrcmpW(findData.cFileName, szDot) || - !lstrcmpW(findData.cFileName, szDotDot)) + if (!strcmpW( findData.cFileName, szDot ) || + !strcmpW( findData.cFileName, szDotDot )) continue; lstrcpyW(subpath, dir); diff --git a/reactos/dll/win32/msi/assembly.c b/reactos/dll/win32/msi/assembly.c new file mode 100644 index 00000000000..5199a31fc70 --- /dev/null +++ b/reactos/dll/win32/msi/assembly.c @@ -0,0 +1,629 @@ +/* + * Implementation of the Microsoft Installer (msi.dll) + * + * Copyright 2010 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msipriv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msi); + +static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD ); +static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD ); +static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD ); +static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * ); +static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * ); + +static BOOL init_function_pointers( void ) +{ + static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0}; + static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0}; + static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0}; + HMODULE hfusion11 = NULL, hfusion20 = NULL, hmscoree, hsxs; + + if (pCreateAssemblyCacheNet11 || pCreateAssemblyCacheNet20) return TRUE; + + if (!(hmscoree = LoadLibraryA( "mscoree.dll" ))) return FALSE; + if (!(pGetFileVersion = (void *)GetProcAddress( hmscoree, "GetFileVersion" ))) goto error; + if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" ))) goto error; + + if (!pLoadLibraryShim( szFusion, szVersion11, NULL, &hfusion11 )) + pCreateAssemblyCacheNet11 = (void *)GetProcAddress( hfusion11, "CreateAssemblyCache" ); + + if (!pLoadLibraryShim( szFusion, szVersion20, NULL, &hfusion20 )) + pCreateAssemblyCacheNet20 = (void *)GetProcAddress( hfusion20, "CreateAssemblyCache" ); + + if (!pCreateAssemblyCacheNet11 && !pCreateAssemblyCacheNet20) goto error; + + if (!(hsxs = LoadLibraryA( "sxs.dll" ))) goto error; + if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" ))) goto error; + return TRUE; + +error: + pCreateAssemblyCacheNet11 = NULL; + pCreateAssemblyCacheNet20 = NULL; + FreeLibrary( hfusion11 ); + FreeLibrary( hfusion20 ); + FreeLibrary( hmscoree ); + return FALSE; +} + +static BOOL init_assembly_caches( MSIPACKAGE *package ) +{ + if (!init_function_pointers()) return FALSE; + if (package->cache_net[CLR_VERSION_V11] || package->cache_net[CLR_VERSION_V20]) return TRUE; + if (pCreateAssemblyCacheSxs( &package->cache_sxs, 0 ) != S_OK) return FALSE; + + if (pCreateAssemblyCacheNet11) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V11], 0 ); + if (pCreateAssemblyCacheNet20) pCreateAssemblyCacheNet20( &package->cache_net[CLR_VERSION_V20], 0 ); + + if (package->cache_net[CLR_VERSION_V11] || package->cache_net[CLR_VERSION_V20]) + { + return TRUE; + } + if (package->cache_net[CLR_VERSION_V11]) + { + IAssemblyCache_Release( package->cache_net[CLR_VERSION_V11] ); + package->cache_net[CLR_VERSION_V11] = NULL; + } + if (package->cache_net[CLR_VERSION_V20]) + { + IAssemblyCache_Release( package->cache_net[CLR_VERSION_V20] ); + package->cache_net[CLR_VERSION_V20] = NULL; + } + IAssemblyCache_Release( package->cache_sxs ); + package->cache_sxs = NULL; + return FALSE; +} + +static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp ) +{ + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','M','s','i','A','s','s','e','m','b','l','y','`',' ', + 'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`', + ' ','=',' ','\'','%','s','\'',0}; + MSIQUERY *view; + MSIRECORD *rec; + UINT r; + + r = MSI_OpenQuery( package->db, &view, query, comp ); + if (r != ERROR_SUCCESS) + return NULL; + + r = MSI_ViewExecute( view, NULL ); + if (r != ERROR_SUCCESS) + { + msiobj_release( &view->hdr ); + return NULL; + } + r = MSI_ViewFetch( view, &rec ); + if (r != ERROR_SUCCESS) + { + msiobj_release( &view->hdr ); + return NULL; + } + if (!MSI_RecordGetString( rec, 4 )) + TRACE("component is a global assembly\n"); + + msiobj_release( &view->hdr ); + return rec; +} + +struct assembly_name +{ + UINT count; + UINT index; + WCHAR **attrs; +}; + +static UINT get_assembly_name_attribute( MSIRECORD *rec, LPVOID param ) +{ + static const WCHAR fmtW[] = {'%','s','=','"','%','s','"',0}; + static const WCHAR nameW[] = {'n','a','m','e',0}; + struct assembly_name *name = param; + const WCHAR *attr = MSI_RecordGetString( rec, 2 ); + const WCHAR *value = MSI_RecordGetString( rec, 3 ); + int len = strlenW( fmtW ) + strlenW( attr ) + strlenW( value ); + + if (!(name->attrs[name->index] = msi_alloc( len * sizeof(WCHAR) ))) + return ERROR_OUTOFMEMORY; + + if (!strcmpiW( attr, nameW )) strcpyW( name->attrs[name->index++], value ); + else sprintfW( name->attrs[name->index++], fmtW, attr, value ); + return ERROR_SUCCESS; +} + +static WCHAR *get_assembly_display_name( MSIDATABASE *db, const WCHAR *comp, MSIASSEMBLY *assembly ) +{ + static const WCHAR commaW[] = {',',0}; + static const WCHAR queryW[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','M','s','i','A','s','s','e','m','b','l','y','N','a','m','e','`',' ', + 'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`', + ' ','=',' ','\'','%','s','\'',0}; + struct assembly_name name; + WCHAR *display_name = NULL; + MSIQUERY *view; + UINT i, r; + int len; + + r = MSI_OpenQuery( db, &view, queryW, comp ); + if (r != ERROR_SUCCESS) + return NULL; + + name.count = 0; + name.index = 0; + name.attrs = NULL; + MSI_IterateRecords( view, &name.count, NULL, NULL ); + if (!name.count) goto done; + + name.attrs = msi_alloc( name.count * sizeof(WCHAR *) ); + if (!name.attrs) goto done; + + MSI_IterateRecords( view, NULL, get_assembly_name_attribute, &name ); + + len = 0; + for (i = 0; i < name.count; i++) len += strlenW( name.attrs[i] ) + 1; + + display_name = msi_alloc( (len + 1) * sizeof(WCHAR) ); + if (display_name) + { + display_name[0] = 0; + for (i = 0; i < name.count; i++) + { + strcatW( display_name, name.attrs[i] ); + if (i < name.count - 1) strcatW( display_name, commaW ); + } + } + +done: + msiobj_release( &view->hdr ); + for (i = 0; i < name.count; i++) msi_free( name.attrs[i] ); + msi_free( name.attrs ); + return display_name; +} + +static BOOL is_assembly_installed( IAssemblyCache *cache, const WCHAR *display_name ) +{ + HRESULT hr; + ASSEMBLY_INFO info; + + memset( &info, 0, sizeof(info) ); + info.cbAssemblyInfo = sizeof(info); + hr = IAssemblyCache_QueryAssemblyInfo( cache, QUERYASMINFO_FLAG_GETSIZE, display_name, &info ); + if (FAILED( hr )) + { + TRACE("QueryAssemblyInfo returned 0x%08x\n", hr); + return FALSE; + } + return (info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED); +} + +static const WCHAR clr_version_v11[] = {'v','1','.','1','.','4','3','2','2',0}; +static const WCHAR clr_version_v20[] = {'v','2','.','0','.','5','0','7','2','7',0}; +static const WCHAR clr_version_unknown[] = {'u','n','k','n','o','w','n',0}; + +static const WCHAR *clr_version[] = +{ + clr_version_v11, + clr_version_v20 +}; + +static const WCHAR *get_clr_version_str( enum clr_version version ) +{ + if (version >= sizeof(clr_version)/sizeof(clr_version[0])) return clr_version_unknown; + return clr_version[version]; +} + +MSIASSEMBLY *load_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) +{ + MSIRECORD *rec; + MSIASSEMBLY *a; + + if (!(rec = get_assembly_record( package, comp->Component ))) return NULL; + if (!init_assembly_caches( package )) + { + ERR("can't initialize assembly caches\n"); + msiobj_release( &rec->hdr ); + return NULL; + } + if (!(a = msi_alloc_zero( sizeof(MSIASSEMBLY) ))) + { + msiobj_release( &rec->hdr ); + return NULL; + } + a->feature = strdupW( MSI_RecordGetString( rec, 2 ) ); + TRACE("feature %s\n", debugstr_w(a->feature)); + + a->manifest = strdupW( MSI_RecordGetString( rec, 3 ) ); + TRACE("manifest %s\n", debugstr_w(a->manifest)); + + a->application = strdupW( MSI_RecordGetString( rec, 4 ) ); + TRACE("application %s\n", debugstr_w(a->application)); + + a->attributes = MSI_RecordGetInteger( rec, 5 ); + TRACE("attributes %u\n", a->attributes); + + if (!(a->display_name = get_assembly_display_name( package->db, comp->Component, a ))) + { + WARN("can't get display name\n"); + msiobj_release( &rec->hdr ); + msi_free( a->feature ); + msi_free( a->manifest ); + msi_free( a->application ); + msi_free( a ); + return NULL; + } + TRACE("display name %s\n", debugstr_w(a->display_name)); + + if (a->application) + { + /* We can't check the manifest here because the target path may still change. + So we assume that the assembly is not installed and lean on the InstallFiles + action to determine which files need to be installed. + */ + a->installed = FALSE; + } + else + { + if (a->attributes == msidbAssemblyAttributesWin32) + a->installed = is_assembly_installed( package->cache_sxs, a->display_name ); + else + { + UINT i; + for (i = 0; i < CLR_VERSION_MAX; i++) + { + a->clr_version[i] = is_assembly_installed( package->cache_net[i], a->display_name ); + if (a->clr_version[i]) + { + TRACE("runtime version %s\n", debugstr_w(get_clr_version_str( i ))); + a->installed = TRUE; + } + } + } + } + TRACE("assembly is %s\n", a->installed ? "installed" : "not installed"); + msiobj_release( &rec->hdr ); + return a; +} + +static enum clr_version get_clr_version( const WCHAR *filename ) +{ + DWORD len; + HRESULT hr; + enum clr_version version = CLR_VERSION_V11; + WCHAR *strW; + + hr = pGetFileVersion( filename, NULL, 0, &len ); + if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) return CLR_VERSION_V11; + if ((strW = msi_alloc( len * sizeof(WCHAR) ))) + { + hr = pGetFileVersion( filename, strW, len, &len ); + if (hr == S_OK) + { + UINT i; + for (i = 0; i < CLR_VERSION_MAX; i++) + if (!strcmpW( strW, clr_version[i] )) version = i; + } + msi_free( strW ); + } + return version; +} + +UINT install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) +{ + HRESULT hr; + const WCHAR *manifest; + IAssemblyCache *cache; + MSIASSEMBLY *assembly = comp->assembly; + MSIFEATURE *feature = NULL; + + if (comp->assembly->feature) + feature = get_loaded_feature( package, comp->assembly->feature ); + + if (assembly->application) + { + if (feature) feature->Action = INSTALLSTATE_LOCAL; + return ERROR_SUCCESS; + } + if (assembly->attributes == msidbAssemblyAttributesWin32) + { + if (!assembly->manifest) + { + WARN("no manifest\n"); + return ERROR_FUNCTION_FAILED; + } + manifest = get_loaded_file( package, assembly->manifest )->TargetPath; + cache = package->cache_sxs; + } + else + { + manifest = get_loaded_file( package, comp->KeyPath )->TargetPath; + cache = package->cache_net[get_clr_version( manifest )]; + } + TRACE("installing assembly %s\n", debugstr_w(manifest)); + + hr = IAssemblyCache_InstallAssembly( cache, 0, manifest, NULL ); + if (hr != S_OK) + { + ERR("Failed to install assembly %s (0x%08x)\n", debugstr_w(manifest), hr); + return ERROR_FUNCTION_FAILED; + } + if (feature) feature->Action = INSTALLSTATE_LOCAL; + assembly->installed = TRUE; + return ERROR_SUCCESS; +} + +static WCHAR *build_local_assembly_path( const WCHAR *filename ) +{ + UINT i; + WCHAR *ret; + + if (!(ret = msi_alloc( (strlenW( filename ) + 1) * sizeof(WCHAR) ))) + return NULL; + + for (i = 0; filename[i]; i++) + { + if (filename[i] == '\\' || filename[i] == '/') ret[i] = '|'; + else ret[i] = filename[i]; + } + ret[i] = 0; + return ret; +} + +static LONG open_assemblies_key( UINT context, BOOL win32, HKEY *hkey ) +{ + static const WCHAR path_win32[] = + {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', + 'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',0}; + static const WCHAR path_dotnet[] = + {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', + 'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',0}; + static const WCHAR classes_path_win32[] = + {'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',0}; + static const WCHAR classes_path_dotnet[] = + {'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',0}; + HKEY root; + const WCHAR *path; + + if (context == MSIINSTALLCONTEXT_MACHINE) + { + root = HKEY_CLASSES_ROOT; + if (win32) path = classes_path_win32; + else path = classes_path_dotnet; + } + else + { + root = HKEY_CURRENT_USER; + if (win32) path = path_win32; + else path = path_dotnet; + } + return RegCreateKeyW( root, path, hkey ); +} + +static LONG open_local_assembly_key( UINT context, BOOL win32, const WCHAR *filename, HKEY *hkey ) +{ + LONG res; + HKEY root; + WCHAR *path; + + if (!(path = build_local_assembly_path( filename ))) + return ERROR_OUTOFMEMORY; + + if ((res = open_assemblies_key( context, win32, &root ))) + { + msi_free( path ); + return res; + } + res = RegCreateKeyW( root, path, hkey ); + RegCloseKey( root ); + msi_free( path ); + return res; +} + +static LONG delete_local_assembly_key( UINT context, BOOL win32, const WCHAR *filename ) +{ + LONG res; + HKEY root; + WCHAR *path; + + if (!(path = build_local_assembly_path( filename ))) + return ERROR_OUTOFMEMORY; + + if ((res = open_assemblies_key( context, win32, &root ))) + { + msi_free( path ); + return res; + } + res = RegDeleteKeyW( root, path ); + RegCloseKey( root ); + msi_free( path ); + return res; +} + +static LONG open_global_assembly_key( UINT context, BOOL win32, HKEY *hkey ) +{ + static const WCHAR path_win32[] = + {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', + 'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\', + 'G','l','o','b','a','l',0}; + static const WCHAR path_dotnet[] = + {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', + 'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\', + 'G','l','o','b','a','l',0}; + static const WCHAR classes_path_win32[] = + {'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\', + 'G','l','o','b','a','l',0}; + static const WCHAR classes_path_dotnet[] = + {'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\','G','l','o','b','a','l',0}; + HKEY root; + const WCHAR *path; + + if (context == MSIINSTALLCONTEXT_MACHINE) + { + root = HKEY_CLASSES_ROOT; + if (win32) path = classes_path_win32; + else path = classes_path_dotnet; + } + else + { + root = HKEY_CURRENT_USER; + if (win32) path = path_win32; + else path = path_dotnet; + } + return RegCreateKeyW( root, path, hkey ); +} + +UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package ) +{ + MSICOMPONENT *comp; + + LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry) + { + LONG res; + HKEY hkey; + GUID guid; + DWORD size; + WCHAR buffer[43]; + MSIRECORD *uirow; + MSIASSEMBLY *assembly = comp->assembly; + BOOL win32; + + if (!assembly || !comp->ComponentId) continue; + + if (!comp->Enabled) + { + TRACE("component is disabled: %s\n", debugstr_w(comp->Component)); + continue; + } + + if (comp->ActionRequest != INSTALLSTATE_LOCAL) + { + TRACE("Component not scheduled for installation: %s\n", debugstr_w(comp->Component)); + comp->Action = comp->Installed; + continue; + } + comp->Action = INSTALLSTATE_LOCAL; + + TRACE("publishing %s\n", debugstr_w(comp->Component)); + + CLSIDFromString( package->ProductCode, &guid ); + encode_base85_guid( &guid, buffer ); + buffer[20] = '>'; + CLSIDFromString( comp->ComponentId, &guid ); + encode_base85_guid( &guid, buffer + 21 ); + buffer[42] = 0; + + win32 = assembly->attributes & msidbAssemblyAttributesWin32; + if (assembly->application) + { + MSIFILE *file = get_loaded_file( package, assembly->application ); + if ((res = open_local_assembly_key( package->Context, win32, file->TargetPath, &hkey ))) + { + WARN("failed to open local assembly key %d\n", res); + return ERROR_FUNCTION_FAILED; + } + } + else + { + if ((res = open_global_assembly_key( package->Context, win32, &hkey ))) + { + WARN("failed to open global assembly key %d\n", res); + return ERROR_FUNCTION_FAILED; + } + } + size = sizeof(buffer); + if ((res = RegSetValueExW( hkey, assembly->display_name, 0, REG_MULTI_SZ, (const BYTE *)buffer, size ))) + { + WARN("failed to set assembly value %d\n", res); + } + RegCloseKey( hkey ); + + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 2, assembly->display_name ); + ui_actiondata( package, szMsiPublishAssemblies, uirow ); + msiobj_release( &uirow->hdr ); + } + return ERROR_SUCCESS; +} + +UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package ) +{ + MSICOMPONENT *comp; + + LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry) + { + LONG res; + MSIRECORD *uirow; + MSIASSEMBLY *assembly = comp->assembly; + BOOL win32; + + if (!assembly || !comp->ComponentId) continue; + + if (!comp->Enabled) + { + TRACE("component is disabled: %s\n", debugstr_w(comp->Component)); + continue; + } + + if (comp->ActionRequest != INSTALLSTATE_ABSENT) + { + TRACE("Component not scheduled for removal: %s\n", debugstr_w(comp->Component)); + comp->Action = comp->Installed; + continue; + } + comp->Action = INSTALLSTATE_ABSENT; + + TRACE("unpublishing %s\n", debugstr_w(comp->Component)); + + win32 = assembly->attributes & msidbAssemblyAttributesWin32; + if (assembly->application) + { + MSIFILE *file = get_loaded_file( package, assembly->application ); + if ((res = delete_local_assembly_key( package->Context, win32, file->TargetPath ))) + WARN("failed to delete local assembly key %d\n", res); + } + else + { + HKEY hkey; + if ((res = open_global_assembly_key( package->Context, win32, &hkey ))) + WARN("failed to delete global assembly key %d\n", res); + else + { + if ((res = RegDeleteValueW( hkey, assembly->display_name ))) + WARN("failed to delete global assembly value %d\n", res); + RegCloseKey( hkey ); + } + } + + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 2, assembly->display_name ); + ui_actiondata( package, szMsiPublishAssemblies, uirow ); + msiobj_release( &uirow->hdr ); + } + return ERROR_SUCCESS; +} diff --git a/reactos/dll/win32/msi/classes.c b/reactos/dll/win32/msi/classes.c index beaf1f0ff93..d11f48b4eab 100644 --- a/reactos/dll/win32/msi/classes.c +++ b/reactos/dll/win32/msi/classes.c @@ -87,7 +87,7 @@ static MSIAPPID *load_given_appid( MSIPACKAGE *package, LPCWSTR name ) /* check for appids already loaded */ LIST_FOR_EACH_ENTRY( appid, &package->appids, MSIAPPID, entry ) { - if (lstrcmpiW( appid->AppID, name )==0) + if (!strcmpiW( appid->AppID, name )) { TRACE("found appid %s %p\n", debugstr_w(name), appid); return appid; @@ -192,7 +192,7 @@ static MSIPROGID *load_given_progid(MSIPACKAGE *package, LPCWSTR name) /* check for progids already loaded */ LIST_FOR_EACH_ENTRY( progid, &package->progids, MSIPROGID, entry ) { - if (strcmpiW( progid->ProgID,name )==0) + if (!strcmpiW( progid->ProgID, name )) { TRACE("found progid %s (%p)\n",debugstr_w(name), progid ); return progid; @@ -323,7 +323,7 @@ static MSICLASS *load_given_class(MSIPACKAGE *package, LPCWSTR classid) /* check for classes already loaded */ LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry ) { - if (lstrcmpiW( cls->clsid, classid )==0) + if (!strcmpiW( cls->clsid, classid )) { TRACE("found class %s (%p)\n",debugstr_w(classid), cls); return cls; @@ -384,7 +384,7 @@ static MSIMIME *load_given_mime( MSIPACKAGE *package, LPCWSTR mime ) /* check for mime already loaded */ LIST_FOR_EACH_ENTRY( mt, &package->mimes, MSIMIME, entry ) { - if (strcmpiW(mt->ContentType,mime)==0) + if (!strcmpiW( mt->ContentType, mime )) { TRACE("found mime %s (%p)\n",debugstr_w(mime), mt); return mt; @@ -458,7 +458,7 @@ static MSIEXTENSION *load_given_extension( MSIPACKAGE *package, LPCWSTR name ) /* check for extensions already loaded */ LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry ) { - if (strcmpiW( ext->Extension, name )==0) + if (!strcmpiW( ext->Extension, name )) { TRACE("extension %s already loaded %p\n", debugstr_w(name), ext); return ext; @@ -578,7 +578,7 @@ static UINT iterate_all_extensions(MSIRECORD *rec, LPVOID param) LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry ) { - if (strcmpiW(extension,ext->Extension)) + if (strcmpiW(extension, ext->Extension)) continue; if (comp == ext->Component) { @@ -850,8 +850,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) } feature->Action = feature->ActionRequest; - file = get_loaded_file( package, comp->KeyPath ); - if (!file) + if (!comp->KeyPath || !(file = get_loaded_file( package, comp->KeyPath ))) { TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid)); continue; diff --git a/reactos/dll/win32/msi/cond.tab.c b/reactos/dll/win32/msi/cond.tab.c index e68723db89b..eff848b5507 100644 --- a/reactos/dll/win32/msi/cond.tab.c +++ b/reactos/dll/win32/msi/cond.tab.c @@ -2323,26 +2323,36 @@ static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b ) switch (operator) { case COND_SS: - return strstrW( a, b ) ? 1 : 0; + return strstrW( a, b ) != 0; case COND_ISS: - return strstriW( a, b ) ? 1 : 0; + return strstriW( a, b ) != 0; case COND_LHS: - return 0 == strncmpW( a, b, lstrlenW( b ) ); + { + int l = strlenW( a ); + int r = strlenW( b ); + if (r > l) return 0; + return !strncmpW( a, b, r ); + } case COND_RHS: { - int l = lstrlenW( a ); - int r = lstrlenW( b ); + int l = strlenW( a ); + int r = strlenW( b ); if (r > l) return 0; - return 0 == lstrcmpW( a + (l - r), b ); + return !strncmpW( a + (l - r), b, r ); } case COND_ILHS: - return 0 == strncmpiW( a, b, lstrlenW( b ) ); + { + int l = strlenW( a ); + int r = strlenW( b ); + if (r > l) return 0; + return !strncmpiW( a, b, r ); + } case COND_IRHS: { - int l = lstrlenW( a ); - int r = lstrlenW( b ); + int l = strlenW( a ); + int r = strlenW( b ); if (r > l) return 0; - return 0 == lstrcmpiW( a + (l - r), b ); + return !strncmpiW( a + (l - r), b, r ); } default: ERR("invalid substring operator\n"); @@ -2367,29 +2377,29 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ) switch (operator) { case COND_LT: - return -1 == lstrcmpW( a, b ); + return strcmpW( a, b ) < 0; case COND_GT: - return 1 == lstrcmpW( a, b ); + return strcmpW( a, b ) > 0; case COND_EQ: - return 0 == lstrcmpW( a, b ); + return strcmpW( a, b ) == 0; case COND_NE: - return 0 != lstrcmpW( a, b ); + return strcmpW( a, b ) != 0; case COND_GE: - return -1 != lstrcmpW( a, b ); + return strcmpW( a, b ) >= 0; case COND_LE: - return 1 != lstrcmpW( a, b ); + return strcmpW( a, b ) <= 0; case COND_ILT: - return -1 == lstrcmpiW( a, b ); + return strcmpiW( a, b ) < 0; case COND_IGT: - return 1 == lstrcmpiW( a, b ); + return strcmpiW( a, b ) > 0; case COND_IEQ: - return 0 == lstrcmpiW( a, b ); + return strcmpiW( a, b ) == 0; case COND_INE: - return 0 != lstrcmpiW( a, b ); + return strcmpiW( a, b ) != 0; case COND_IGE: - return -1 != lstrcmpiW( a, b ); + return strcmpiW( a, b ) >= 0; case COND_ILE: - return 1 != lstrcmpiW( a, b ); + return strcmpiW( a, b ) <= 0; default: ERR("invalid string operator\n"); return 0; diff --git a/reactos/dll/win32/msi/cond.y b/reactos/dll/win32/msi/cond.y index 03ea4938ade..5bde044d8c2 100644 --- a/reactos/dll/win32/msi/cond.y +++ b/reactos/dll/win32/msi/cond.y @@ -456,26 +456,36 @@ static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b ) switch (operator) { case COND_SS: - return strstrW( a, b ) ? 1 : 0; + return strstrW( a, b ) != 0; case COND_ISS: - return strstriW( a, b ) ? 1 : 0; + return strstriW( a, b ) != 0; case COND_LHS: - return 0 == strncmpW( a, b, lstrlenW( b ) ); + { + int l = strlenW( a ); + int r = strlenW( b ); + if (r > l) return 0; + return !strncmpW( a, b, r ); + } case COND_RHS: { - int l = lstrlenW( a ); - int r = lstrlenW( b ); + int l = strlenW( a ); + int r = strlenW( b ); if (r > l) return 0; - return 0 == lstrcmpW( a + (l - r), b ); + return !strncmpW( a + (l - r), b, r ); } case COND_ILHS: - return 0 == strncmpiW( a, b, lstrlenW( b ) ); + { + int l = strlenW( a ); + int r = strlenW( b ); + if (r > l) return 0; + return !strncmpiW( a, b, r ); + } case COND_IRHS: { - int l = lstrlenW( a ); - int r = lstrlenW( b ); + int l = strlenW( a ); + int r = strlenW( b ); if (r > l) return 0; - return 0 == lstrcmpiW( a + (l - r), b ); + return !strncmpiW( a + (l - r), b, r ); } default: ERR("invalid substring operator\n"); @@ -500,29 +510,29 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ) switch (operator) { case COND_LT: - return -1 == lstrcmpW( a, b ); + return strcmpW( a, b ) < 0; case COND_GT: - return 1 == lstrcmpW( a, b ); + return strcmpW( a, b ) > 0; case COND_EQ: - return 0 == lstrcmpW( a, b ); + return strcmpW( a, b ) == 0; case COND_NE: - return 0 != lstrcmpW( a, b ); + return strcmpW( a, b ) != 0; case COND_GE: - return -1 != lstrcmpW( a, b ); + return strcmpW( a, b ) >= 0; case COND_LE: - return 1 != lstrcmpW( a, b ); + return strcmpW( a, b ) <= 0; case COND_ILT: - return -1 == lstrcmpiW( a, b ); + return strcmpiW( a, b ) < 0; case COND_IGT: - return 1 == lstrcmpiW( a, b ); + return strcmpiW( a, b ) > 0; case COND_IEQ: - return 0 == lstrcmpiW( a, b ); + return strcmpiW( a, b ) == 0; case COND_INE: - return 0 != lstrcmpiW( a, b ); + return strcmpiW( a, b ) != 0; case COND_IGE: - return -1 != lstrcmpiW( a, b ); + return strcmpiW( a, b ) >= 0; case COND_ILE: - return 1 != lstrcmpiW( a, b ); + return strcmpiW( a, b ) <= 0; default: ERR("invalid string operator\n"); return 0; diff --git a/reactos/dll/win32/msi/create.c b/reactos/dll/win32/msi/create.c index 2e13d592552..c55390c8f7a 100644 --- a/reactos/dll/win32/msi/create.c +++ b/reactos/dll/win32/msi/create.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winerror.h" #include "wine/debug.h" +#include "wine/unicode.h" #include "msi.h" #include "msiquery.h" #include "objbase.h" @@ -153,7 +154,7 @@ static UINT check_columns( const column_info *col_info ) /* check for two columns with the same name */ for( c1 = col_info; c1; c1 = c1->next ) for( c2 = c1->next; c2; c2 = c2->next ) - if (!lstrcmpW(c1->column, c2->column)) + if (!strcmpW( c1->column, c2->column )) return ERROR_BAD_QUERY_SYNTAX; return ERROR_SUCCESS; diff --git a/reactos/dll/win32/msi/custom.c b/reactos/dll/win32/msi/custom.c index b56139fb665..83a750dd578 100644 --- a/reactos/dll/win32/msi/custom.c +++ b/reactos/dll/win32/msi/custom.c @@ -236,7 +236,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL } else if (type & msidbCustomActionTypeRollback) { - FIXME("Deferring rollback only action... rollbacks not supported yet\n"); + FIXME("Deferring rollback only action\n"); schedule_action(package, ROLLBACK_SCRIPT, deferred); } else @@ -274,6 +274,12 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL msi_free(actiondata); } + if (type & msidbCustomActionTypeRollback) + { + FIXME("Rollbacks not supported yet\n"); + rc = ERROR_SUCCESS; + goto end; + } } else if (!check_execution_scheduling_options(package,action,type)) { @@ -355,60 +361,88 @@ end: return rc; } - -static UINT store_binary_to_temp(MSIPACKAGE *package, LPCWSTR source, - LPWSTR tmp_file) +static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll ) { static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', '`','B','i' ,'n','a','r','y','`',' ','W','H','E','R','E',' ', '`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0}; - MSIRECORD *row = 0; + MSIRECORD *row; + MSIBINARY *binary; HANDLE file; CHAR buffer[1024]; - WCHAR fmt[MAX_PATH]; - DWORD sz = MAX_PATH; + WCHAR fmt[MAX_PATH], tmpfile[MAX_PATH]; + DWORD sz = MAX_PATH, write; UINT r; if (msi_get_property(package->db, cszTempFolder, fmt, &sz) != ERROR_SUCCESS) GetTempPathW(MAX_PATH, fmt); - if (GetTempFileNameW(fmt, szMsi, 0, tmp_file) == 0) + if (!GetTempFileNameW( fmt, szMsi, 0, tmpfile )) { - TRACE("Unable to create file\n"); - return ERROR_FUNCTION_FAILED; + TRACE("unable to create temp file %s (%u)\n", debugstr_w(tmpfile), GetLastError()); + return NULL; } - track_tempfile(package, tmp_file); row = MSI_QueryGetRecord(package->db, query, source); if (!row) - return ERROR_FUNCTION_FAILED; + return NULL; - /* write out the file */ - file = CreateFileW(tmp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - if (file == INVALID_HANDLE_VALUE) - r = ERROR_FUNCTION_FAILED; - else + if (!(binary = msi_alloc_zero( sizeof(MSIBINARY) ))) { - do + msiobj_release( &row->hdr ); + return NULL; + } + file = CreateFileW( tmpfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + if (file == INVALID_HANDLE_VALUE) + { + msiobj_release( &row->hdr ); + msi_free( binary ); + return NULL; + } + do + { + sz = sizeof(buffer); + r = MSI_RecordReadStream( row, 2, buffer, &sz ); + if (r != ERROR_SUCCESS) { - DWORD write; - sz = sizeof buffer; - r = MSI_RecordReadStream(row, 2, buffer, &sz); - if (r != ERROR_SUCCESS) - { - ERR("Failed to get stream\n"); - break; - } - WriteFile(file, buffer, sz, &write, NULL); - } while (sz == sizeof buffer); - CloseHandle(file); + ERR("Failed to get stream\n"); + break; + } + WriteFile( file, buffer, sz, &write, NULL ); + } while (sz == sizeof buffer); + + CloseHandle( file ); + msiobj_release( &row->hdr ); + if (r != ERROR_SUCCESS) + { + DeleteFileW( tmpfile ); + msi_free( binary ); + return NULL; } - msiobj_release(&row->hdr); + /* keep a reference to prevent the dll from being unloaded */ + if (dll && !(binary->module = LoadLibraryW( tmpfile ))) + { + WARN( "failed to load dll %s (%u)\n", debugstr_w( tmpfile ), GetLastError() ); + } + binary->source = strdupW( source ); + binary->tmpfile = strdupW( tmpfile ); + list_add_tail( &package->binaries, &binary->entry ); + return binary; +} - return r; +static MSIBINARY *get_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll ) +{ + MSIBINARY *binary; + + LIST_FOR_EACH_ENTRY( binary, &package->binaries, MSIBINARY, entry ) + { + if (!strcmpW( binary->source, source )) + return binary; + } + + return create_temp_binary( package, source, dll ); } static void file_running_action(MSIPACKAGE* package, HANDLE Handle, @@ -594,7 +628,7 @@ static void handle_msi_break( LPCWSTR target ) if( !GetEnvironmentVariableW( MsiBreak, val, MAX_PATH )) return; - if( lstrcmpiW( val, target )) + if( strcmpiW( val, target )) return; msg = msi_alloc( (lstrlenW(format) + 10) * sizeof(WCHAR) ); @@ -615,7 +649,7 @@ static UINT get_action_info( const GUID *guid, INT *type, MSIHANDLE *handle, IWineMsiRemoteCustomAction *rca = NULL; HRESULT r; - r = DllGetClassObject( &CLSID_IWineMsiRemoteCustomAction, + r = DllGetClassObject( &CLSID_WineMsiRemoteCustomAction, &IID_IClassFactory, (LPVOID *)&cf ); if (FAILED(r)) { @@ -683,8 +717,8 @@ static DWORD ACTION_CallDllFunction( const GUID *guid ) hModule = LoadLibraryW( dll ); if (!hModule) { - ERR("failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() ); - return r; + WARN( "failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() ); + return ERROR_SUCCESS; } proc = strdupWtoA( function ); @@ -875,20 +909,15 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source, LPCWSTR target, const INT type, LPCWSTR action) { msi_custom_action_info *info; - WCHAR tmp_file[MAX_PATH]; + MSIBINARY *binary; UINT r; - r = store_binary_to_temp(package, source, tmp_file); - if (r != ERROR_SUCCESS) - return r; + if (!(binary = get_temp_binary( package, source, TRUE ))) + return ERROR_FUNCTION_FAILED; - TRACE("Calling function %s from %s\n",debugstr_w(target), - debugstr_w(tmp_file)); + TRACE("Calling function %s from %s\n", debugstr_w(target), debugstr_w(binary->tmpfile)); - if (!strchrW(tmp_file,'.')) - strcatW(tmp_file, szDot); - - info = do_msidbCustomActionTypeDll( package, type, tmp_file, target, action ); + info = do_msidbCustomActionTypeDll( package, type, binary->tmpfile, target, action ); r = wait_thread_handle( info ); release_custom_action_data( info ); @@ -898,7 +927,6 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source, LPCWSTR target, const INT type, LPCWSTR action) { - WCHAR tmp_file[MAX_PATH]; STARTUPINFOW si; PROCESS_INFORMATION info; BOOL rc; @@ -906,29 +934,27 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source, WCHAR *deformated = NULL; WCHAR *cmd; static const WCHAR spc[] = {' ',0}; + MSIBINARY *binary; UINT r; memset(&si,0,sizeof(STARTUPINFOW)); - r = store_binary_to_temp(package, source, tmp_file); - if (r != ERROR_SUCCESS) - return r; + if (!(binary = get_temp_binary( package, source, FALSE ))) + return ERROR_FUNCTION_FAILED; deformat_string(package,target,&deformated); - len = strlenW(tmp_file)+2; - + len = strlenW( binary->tmpfile ) + 2; if (deformated) len += strlenW(deformated); cmd = msi_alloc(sizeof(WCHAR)*len); - strcpyW(cmd,tmp_file); + strcpyW( cmd, binary->tmpfile ); if (deformated) { strcatW(cmd,spc); strcatW(cmd,deformated); - msi_free(deformated); } @@ -1121,8 +1147,7 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source, memset(&si, 0, sizeof(STARTUPINFOW)); - workingdir = resolve_folder(package, source, FALSE, FALSE, TRUE, NULL); - + workingdir = resolve_target_folder( package, source, FALSE, TRUE, NULL ); if (!workingdir) return ERROR_FUNCTION_FAILED; @@ -1161,13 +1186,13 @@ static DWORD ACTION_CallScript( const GUID *guid ) { msi_custom_action_info *info; MSIHANDLE hPackage; - UINT r = ERROR_FUNCTION_FAILED; + UINT r; info = find_action_by_guid( guid ); if (!info) { ERR("failed to find action %s\n", debugstr_guid( guid) ); - return r; + return ERROR_FUNCTION_FAILED; } TRACE("function %s, script %s\n", debugstr_w( info->target ), debugstr_w( info->source ) ); @@ -1176,13 +1201,13 @@ static DWORD ACTION_CallScript( const GUID *guid ) if (hPackage) { r = call_script( hPackage, info->type, info->source, info->target, info->action ); + TRACE("script returned %u\n", r); MsiCloseHandle( hPackage ); } else ERR("failed to create handle for %p\n", info->package ); release_custom_action_data( info ); - return S_OK; } @@ -1433,13 +1458,13 @@ void ACTION_FinishCustomActions(const MSIPACKAGE* package) } typedef struct _msi_custom_remote_impl { - const IWineMsiRemoteCustomActionVtbl *lpVtbl; + IWineMsiRemoteCustomAction IWineMsiRemoteCustomAction_iface; LONG refs; } msi_custom_remote_impl; -static inline msi_custom_remote_impl* mcr_from_IWineMsiRemoteCustomAction( IWineMsiRemoteCustomAction* iface ) +static inline msi_custom_remote_impl *impl_from_IWineMsiRemoteCustomAction( IWineMsiRemoteCustomAction *iface ) { - return (msi_custom_remote_impl*) iface; + return CONTAINING_RECORD(iface, msi_custom_remote_impl, IWineMsiRemoteCustomAction_iface); } static HRESULT WINAPI mcr_QueryInterface( IWineMsiRemoteCustomAction *iface, @@ -1458,14 +1483,14 @@ static HRESULT WINAPI mcr_QueryInterface( IWineMsiRemoteCustomAction *iface, static ULONG WINAPI mcr_AddRef( IWineMsiRemoteCustomAction *iface ) { - msi_custom_remote_impl* This = mcr_from_IWineMsiRemoteCustomAction( iface ); + msi_custom_remote_impl* This = impl_from_IWineMsiRemoteCustomAction( iface ); return InterlockedIncrement( &This->refs ); } static ULONG WINAPI mcr_Release( IWineMsiRemoteCustomAction *iface ) { - msi_custom_remote_impl* This = mcr_from_IWineMsiRemoteCustomAction( iface ); + msi_custom_remote_impl* This = impl_from_IWineMsiRemoteCustomAction( iface ); ULONG r; r = InterlockedDecrement( &This->refs ); @@ -1508,7 +1533,7 @@ HRESULT create_msi_custom_remote( IUnknown *pOuter, LPVOID *ppObj ) if (!This) return E_OUTOFMEMORY; - This->lpVtbl = &msi_custom_remote_vtbl; + This->IWineMsiRemoteCustomAction_iface.lpVtbl = &msi_custom_remote_vtbl; This->refs = 1; *ppObj = This; diff --git a/reactos/dll/win32/msi/database.c b/reactos/dll/win32/msi/database.c index 3007d485b2b..598d7a8a022 100644 --- a/reactos/dll/win32/msi/database.c +++ b/reactos/dll/win32/msi/database.c @@ -19,6 +19,7 @@ */ #include +#include #define COBJMACROS #define NONAMELESSUNION @@ -79,7 +80,7 @@ static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm ) continue; } - if( !lstrcmpW( name, stat.pwcsName ) ) + if( !strcmpW( name, stat.pwcsName ) ) { TRACE("found %s\n", debugstr_w(name)); *stm = stream->stm; @@ -888,6 +889,8 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file) static const WCHAR suminfo[] = {'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0}; + static const WCHAR forcecodepage[] = + {'_','F','o','r','c','e','C','o','d','e','p','a','g','e',0}; TRACE("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) ); @@ -910,6 +913,13 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file) msi_parse_line( &ptr, &types, &num_types ); msi_parse_line( &ptr, &labels, &num_labels ); + if (num_columns == 1 && !columns[0][0] && num_labels == 1 && !labels[0][0] && + num_types == 2 && !strcmpW( types[1], forcecodepage )) + { + r = msi_set_string_table_codepage( db->strings, atoiW( types[0] ) ); + goto done; + } + if (num_columns != num_types) { r = ERROR_FUNCTION_FAILED; @@ -1087,13 +1097,13 @@ static UINT msi_export_row( MSIRECORD *row, void *arg ) return msi_export_record( arg, row, 1 ); } -static UINT msi_export_forcecodepage( HANDLE handle ) +static UINT msi_export_forcecodepage( HANDLE handle, UINT codepage ) { + static const char fmt[] = "\r\n\r\n%u\t_ForceCodepage\r\n"; + char data[sizeof(fmt) + 10]; DWORD sz; - static const char data[] = "\r\n\r\n0\t_ForceCodepage\r\n"; - - FIXME("Read the codepage from the strings table!\n"); + sprintf( data, fmt, codepage ); sz = lstrlenA(data) + 1; if (!WriteFile(handle, data, sz, &sz, NULL)) @@ -1136,9 +1146,10 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, if (handle == INVALID_HANDLE_VALUE) return ERROR_FUNCTION_FAILED; - if (!lstrcmpW( table, forcecodepage )) + if (!strcmpW( table, forcecodepage )) { - r = msi_export_forcecodepage( handle ); + UINT codepage = msi_get_string_table_codepage( db->strings ); + r = msi_export_forcecodepage( handle, codepage ); goto done; } @@ -1319,7 +1330,7 @@ static BOOL merge_type_match(LPCWSTR type1, LPCWSTR type2) ((type2[0] == 'L') || (type2[0] == 'S'))) return TRUE; - return !lstrcmpW(type1, type2); + return !strcmpW( type1, type2 ); } static UINT merge_verify_colnames(MSIQUERY *dbview, MSIQUERY *mergeview) @@ -1341,8 +1352,7 @@ static UINT merge_verify_colnames(MSIQUERY *dbview, MSIQUERY *mergeview) if (!MSI_RecordGetString(mergerec, i)) break; - if (lstrcmpW(MSI_RecordGetString(dbrec, i), - MSI_RecordGetString(mergerec, i))) + if (strcmpW( MSI_RecordGetString( dbrec, i ), MSI_RecordGetString( mergerec, i ) )) { r = ERROR_DATATYPE_MISMATCH; goto done; @@ -1405,8 +1415,7 @@ static UINT merge_verify_primary_keys(MSIDATABASE *db, MSIDATABASE *mergedb, for (i = 1; i <= count; i++) { - if (lstrcmpW(MSI_RecordGetString(dbrec, i), - MSI_RecordGetString(mergerec, i))) + if (strcmpW( MSI_RecordGetString( dbrec, i ), MSI_RecordGetString( mergerec, i ) )) { r = ERROR_DATATYPE_MISMATCH; goto done; @@ -1434,7 +1443,7 @@ static LPWSTR get_key_value(MSIQUERY *view, LPCWSTR key, MSIRECORD *rec) do { str = msi_dup_record_field(colnames, ++i); - cmp = lstrcmpW(key, str); + cmp = strcmpW( key, str ); msi_free(str); } while (cmp); @@ -2029,14 +2038,14 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle ) } typedef struct _msi_remote_database_impl { - const IWineMsiRemoteDatabaseVtbl *lpVtbl; + IWineMsiRemoteDatabase IWineMsiRemoteDatabase_iface; MSIHANDLE database; LONG refs; } msi_remote_database_impl; -static inline msi_remote_database_impl* mrd_from_IWineMsiRemoteDatabase( IWineMsiRemoteDatabase* iface ) +static inline msi_remote_database_impl *impl_from_IWineMsiRemoteDatabase( IWineMsiRemoteDatabase *iface ) { - return (msi_remote_database_impl *)iface; + return CONTAINING_RECORD(iface, msi_remote_database_impl, IWineMsiRemoteDatabase_iface); } static HRESULT WINAPI mrd_QueryInterface( IWineMsiRemoteDatabase *iface, @@ -2055,14 +2064,14 @@ static HRESULT WINAPI mrd_QueryInterface( IWineMsiRemoteDatabase *iface, static ULONG WINAPI mrd_AddRef( IWineMsiRemoteDatabase *iface ) { - msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface ); + msi_remote_database_impl* This = impl_from_IWineMsiRemoteDatabase( iface ); return InterlockedIncrement( &This->refs ); } static ULONG WINAPI mrd_Release( IWineMsiRemoteDatabase *iface ) { - msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface ); + msi_remote_database_impl* This = impl_from_IWineMsiRemoteDatabase( iface ); ULONG r; r = InterlockedDecrement( &This->refs ); @@ -2077,7 +2086,7 @@ static ULONG WINAPI mrd_Release( IWineMsiRemoteDatabase *iface ) static HRESULT WINAPI mrd_IsTablePersistent( IWineMsiRemoteDatabase *iface, LPCWSTR table, MSICONDITION *persistent ) { - msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface ); + msi_remote_database_impl *This = impl_from_IWineMsiRemoteDatabase( iface ); *persistent = MsiDatabaseIsTablePersistentW(This->database, table); return S_OK; } @@ -2085,7 +2094,7 @@ static HRESULT WINAPI mrd_IsTablePersistent( IWineMsiRemoteDatabase *iface, static HRESULT WINAPI mrd_GetPrimaryKeys( IWineMsiRemoteDatabase *iface, LPCWSTR table, MSIHANDLE *keys ) { - msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface ); + msi_remote_database_impl *This = impl_from_IWineMsiRemoteDatabase( iface ); UINT r = MsiDatabaseGetPrimaryKeysW(This->database, table, keys); return HRESULT_FROM_WIN32(r); } @@ -2093,7 +2102,7 @@ static HRESULT WINAPI mrd_GetPrimaryKeys( IWineMsiRemoteDatabase *iface, static HRESULT WINAPI mrd_GetSummaryInformation( IWineMsiRemoteDatabase *iface, UINT updatecount, MSIHANDLE *suminfo ) { - msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface ); + msi_remote_database_impl *This = impl_from_IWineMsiRemoteDatabase( iface ); UINT r = MsiGetSummaryInformationW(This->database, NULL, updatecount, suminfo); return HRESULT_FROM_WIN32(r); } @@ -2101,14 +2110,14 @@ static HRESULT WINAPI mrd_GetSummaryInformation( IWineMsiRemoteDatabase *iface, static HRESULT WINAPI mrd_OpenView( IWineMsiRemoteDatabase *iface, LPCWSTR query, MSIHANDLE *view ) { - msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface ); + msi_remote_database_impl *This = impl_from_IWineMsiRemoteDatabase( iface ); UINT r = MsiDatabaseOpenViewW(This->database, query, view); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrd_SetMsiHandle( IWineMsiRemoteDatabase *iface, MSIHANDLE handle ) { - msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface ); + msi_remote_database_impl* This = impl_from_IWineMsiRemoteDatabase( iface ); This->database = handle; return S_OK; } @@ -2133,7 +2142,7 @@ HRESULT create_msi_remote_database( IUnknown *pOuter, LPVOID *ppObj ) if (!This) return E_OUTOFMEMORY; - This->lpVtbl = &msi_remote_database_vtbl; + This->IWineMsiRemoteDatabase_iface.lpVtbl = &msi_remote_database_vtbl; This->database = 0; This->refs = 1; diff --git a/reactos/dll/win32/msi/dialog.c b/reactos/dll/win32/msi/dialog.c index e0e27d129f4..40aa7dff692 100644 --- a/reactos/dll/win32/msi/dialog.c +++ b/reactos/dll/win32/msi/dialog.c @@ -73,7 +73,7 @@ struct msi_control_tag typedef struct msi_font_tag { - struct msi_font_tag *next; + struct list entry; HFONT hfont; COLORREF color; WCHAR name[1]; @@ -90,7 +90,7 @@ struct msi_dialog_tag SIZE size; HWND hwnd; LPWSTR default_font; - msi_font *font_list; + struct list fonts; struct list controls; HWND hWndFocus; LPWSTR control_default; @@ -310,8 +310,7 @@ static UINT msi_dialog_add_font( MSIRECORD *rec, LPVOID param ) name = MSI_RecordGetString( rec, 1 ); font = msi_alloc( sizeof *font + strlenW( name )*sizeof (WCHAR) ); strcpyW( font->name, name ); - font->next = dialog->font_list; - dialog->font_list = font; + list_add_head( &dialog->fonts, &font->entry ); font->color = MSI_RecordGetInteger( rec, 4 ); @@ -346,9 +345,9 @@ static UINT msi_dialog_add_font( MSIRECORD *rec, LPVOID param ) static msi_font *msi_dialog_find_font( msi_dialog *dialog, LPCWSTR name ) { - msi_font *font; + msi_font *font = NULL; - for( font = dialog->font_list; font; font = font->next ) + LIST_FOR_EACH_ENTRY( font, &dialog->fonts, msi_font, entry ) if( !strcmpW( font->name, name ) ) /* FIXME: case sensitive? */ break; @@ -578,7 +577,7 @@ static void msi_dialog_update_controls( msi_dialog *dialog, LPCWSTR property ) LIST_FOR_EACH_ENTRY( control, &dialog->controls, msi_control, entry ) { - if ( !lstrcmpW( control->property, property ) && control->update ) + if ( control->property && !strcmpW( control->property, property ) && control->update ) control->update( dialog, control ); } } @@ -601,7 +600,7 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, ctrl = msi_dialog_find_control( dialog, control ); if (!ctrl) return; - if( !lstrcmpW(attribute, szText) ) + if( !strcmpW( attribute, szText ) ) { font_text = MSI_RecordGetString( rec , 1 ); font = msi_dialog_get_style( font_text, &text ); @@ -610,7 +609,7 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, msi_free( font ); msi_dialog_check_messages( NULL ); } - else if( !lstrcmpW(attribute, szProgress) ) + else if( !strcmpW( attribute, szProgress ) ) { DWORD func, val; @@ -640,12 +639,12 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, break; } } - else if ( !lstrcmpW(attribute, szProperty) ) + else if ( !strcmpW( attribute, szProperty ) ) { MSIFEATURE *feature = msi_seltree_get_selected_feature( ctrl ); msi_dialog_set_property( dialog->package, ctrl->property, feature->Directory ); } - else if ( !lstrcmpW(attribute, szSelectionPath) ) + else if ( !strcmpW( attribute, szSelectionPath ) ) { LPWSTR prop = msi_dialog_dup_property( dialog, ctrl->property, TRUE ); LPWSTR path; @@ -1368,7 +1367,7 @@ static void msi_dialog_combobox_update( msi_dialog *dialog, for (j = 0; j < info->num_items; j++) { tmp = (LPWSTR) SendMessageW( control->hwnd, CB_GETITEMDATA, j, 0 ); - if (!lstrcmpW( value, tmp )) + if (!strcmpW( value, tmp )) break; } @@ -1743,7 +1742,7 @@ static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD *rec ) font = msi_dialog_get_style( font_mask, &mask ); if( !mask ) { - ERR("mask template is empty\n"); + WARN("mask template is empty\n"); goto end; } @@ -1988,7 +1987,7 @@ static UINT msi_dialog_create_radiobutton( MSIRECORD *rec, LPVOID param ) return ERROR_FUNCTION_FAILED; control->handler = msi_dialog_radiogroup_handler; - if (!lstrcmpW(control->name, group->propval)) + if (group->propval && !strcmpW( control->name, group->propval )) SendMessageW(control->hwnd, BM_SETCHECK, BST_CHECKED, 0); prop = MSI_RecordGetString( rec, 1 ); @@ -2126,9 +2125,9 @@ static void msi_seltree_update_feature_installstate( HWND hwnd, HTREEITEM hItem, MSIPACKAGE *package, MSIFEATURE *feature, INSTALLSTATE state ) { - msi_feature_set_state( package, feature, state ); + feature->ActionRequest = state; msi_seltree_sync_item_state( hwnd, feature, hItem ); - ACTION_UpdateComponentStates( package, feature->Feature ); + ACTION_UpdateComponentStates( package, feature ); } static void @@ -2258,7 +2257,11 @@ msi_seltree_add_child_features( MSIPACKAGE *package, HWND hwnd, LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - if ( lstrcmpW( parent, feature->Feature_Parent ) ) + if ( parent && feature->Feature_Parent && strcmpW( parent, feature->Feature_Parent )) + continue; + else if ( parent && !feature->Feature_Parent ) + continue; + else if ( !parent && feature->Feature_Parent ) continue; if ( !feature->Title ) @@ -2373,14 +2376,19 @@ static UINT msi_dialog_seltree_handler( msi_dialog *dialog, ControlEvent_FireSubscribedEvent( dialog->package, szSelectionDescription, rec ); dir = MSI_RecordGetString( row, 7 ); - folder = get_loaded_folder( dialog->package, dir ); - if (!folder) + if (dir) { - r = ERROR_FUNCTION_FAILED; - goto done; + folder = get_loaded_folder( dialog->package, dir ); + if (!folder) + { + r = ERROR_FUNCTION_FAILED; + goto done; + } + MSI_RecordSetStringW( rec, 1, folder->ResolvedTarget ); } + else + MSI_RecordSetStringW( rec, 1, NULL ); - MSI_RecordSetStringW( rec, 1, folder->ResolvedTarget ); ControlEvent_FireSubscribedEvent( dialog->package, szSelectionPath, rec ); done: @@ -2682,7 +2690,7 @@ static void msi_dialog_update_directory_list( msi_dialog *dialog, msi_control *c if ( wfd.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY ) continue; - if ( !lstrcmpW( wfd.cFileName, szDot ) || !lstrcmpW( wfd.cFileName, szDotDot ) ) + if ( !strcmpW( wfd.cFileName, szDot ) || !strcmpW( wfd.cFileName, szDotDot ) ) continue; item.mask = LVIF_TEXT; @@ -2846,7 +2854,7 @@ static void msi_dialog_vcl_add_columns( msi_dialog *dialog, msi_control *control begin += end - begin + 1; /* empty braces or '0' hides the column */ - if ( !num[0] || !lstrcmpW( num, szZero ) ) + if ( !num[0] || !strcmpW( num, szZero ) ) { count++; msi_free( num ); @@ -3151,15 +3159,15 @@ static UINT msi_dialog_set_control_condition( MSIRECORD *rec, LPVOID param ) TRACE("%s control %s\n", debugstr_w(action), debugstr_w(name)); /* FIXME: case sensitive? */ - if(!lstrcmpW(action, szHide)) + if (!strcmpW( action, szHide )) ShowWindow(control->hwnd, SW_HIDE); - else if(!strcmpW(action, szShow)) + else if (!strcmpW( action, szShow )) ShowWindow(control->hwnd, SW_SHOW); - else if(!strcmpW(action, szDisable)) + else if (!strcmpW( action, szDisable )) EnableWindow(control->hwnd, FALSE); - else if(!strcmpW(action, szEnable)) + else if (!strcmpW( action, szEnable )) EnableWindow(control->hwnd, TRUE); - else if(!strcmpW(action, szDefault)) + else if (!strcmpW( action, szDefault )) SetFocus(control->hwnd); else FIXME("Unhandled action %s\n", debugstr_w(action)); @@ -3844,6 +3852,7 @@ msi_dialog *msi_dialog_create( MSIPACKAGE* package, dialog->event_handler = event_handler; dialog->finished = 0; list_init( &dialog->controls ); + list_init( &dialog->fonts ); /* verify that the dialog exists */ rec = msi_get_dialog_record( dialog ); @@ -3960,6 +3969,8 @@ void msi_dialog_do_preview( msi_dialog *dialog ) void msi_dialog_destroy( msi_dialog *dialog ) { + msi_font *font, *next; + if( uiThreadId != GetCurrentThreadId() ) { SendMessageW( hMsiHiddenWindow, WM_MSI_DIALOG_DESTROY, 0, (LPARAM) dialog ); @@ -3986,12 +3997,11 @@ void msi_dialog_destroy( msi_dialog *dialog ) } /* destroy the list of fonts */ - while( dialog->font_list ) + LIST_FOR_EACH_ENTRY_SAFE( font, next, &dialog->fonts, msi_font, entry ) { - msi_font *t = dialog->font_list; - dialog->font_list = t->next; - DeleteObject( t->hfont ); - msi_free( t ); + list_remove( &font->entry ); + DeleteObject( font->hfont ); + msi_free( font ); } msi_free( dialog->default_font ); @@ -4022,11 +4032,11 @@ static UINT error_dialog_handler(MSIPACKAGE *package, LPCWSTR event, 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0 }; - if ( lstrcmpW( event, end_dialog ) ) + if ( strcmpW( event, end_dialog ) ) return ERROR_SUCCESS; - if ( !lstrcmpW( argument, error_abort ) || !lstrcmpW( argument, error_cancel ) || - !lstrcmpW( argument, error_no ) ) + if ( !strcmpW( argument, error_abort ) || !strcmpW( argument, error_cancel ) || + !strcmpW( argument, error_no ) ) { msi_set_property( package->db, result_prop, error_abort ); } @@ -4108,7 +4118,7 @@ UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR er if ( r != ERROR_SUCCESS) r = ERROR_SUCCESS; - if ( !lstrcmpW( result, error_abort ) ) + if ( !strcmpW( result, error_abort ) ) r = ERROR_FUNCTION_FAILED; done: diff --git a/reactos/dll/win32/msi/events.c b/reactos/dll/win32/msi/events.c index 157d18575f4..b888c1cada9 100644 --- a/reactos/dll/win32/msi/events.c +++ b/reactos/dll/win32/msi/events.c @@ -90,22 +90,18 @@ static UINT event_do_dialog( MSIPACKAGE *package, LPCWSTR name, msi_dialog *pare static UINT ControlEvent_EndDialog(MSIPACKAGE* package, LPCWSTR argument, msi_dialog* dialog) { - static const WCHAR szExit[] = { - 'E','x','i','t',0}; - static const WCHAR szRetry[] = { - 'R','e','t','r','y',0}; - static const WCHAR szIgnore[] = { - 'I','g','n','o','r','e',0}; - static const WCHAR szReturn[] = { - 'R','e','t','u','r','n',0}; + static const WCHAR szExit[] = {'E','x','i','t',0}; + static const WCHAR szRetry[] = {'R','e','t','r','y',0}; + static const WCHAR szIgnore[] = {'I','g','n','o','r','e',0}; + static const WCHAR szReturn[] = {'R','e','t','u','r','n',0}; - if (lstrcmpW(argument,szExit)==0) + if (!strcmpW( argument, szExit )) package->CurrentInstallState = ERROR_INSTALL_USEREXIT; - else if (lstrcmpW(argument, szRetry) == 0) + else if (!strcmpW( argument, szRetry )) package->CurrentInstallState = ERROR_INSTALL_SUSPEND; - else if (lstrcmpW(argument, szIgnore) == 0) + else if (!strcmpW( argument, szIgnore )) package->CurrentInstallState = ERROR_SUCCESS; - else if (lstrcmpW(argument, szReturn) == 0) + else if (!strcmpW( argument, szReturn )) { msi_dialog *parent = msi_dialog_get_parent(dialog); msi_free(package->next_dialog); @@ -167,58 +163,50 @@ static UINT ControlEvent_DoAction(MSIPACKAGE* package, LPCWSTR argument, return ERROR_SUCCESS; } -static UINT ControlEvent_AddLocal(MSIPACKAGE* package, LPCWSTR argument, - msi_dialog* dialog) +static UINT ControlEvent_AddLocal( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog ) { - MSIFEATURE *feature = NULL; + MSIFEATURE *feature; - if (lstrcmpW(szAll,argument)) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - MSI_SetFeatureStateW(package,argument,INSTALLSTATE_LOCAL); - } - else - { - LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) - msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL); - - ACTION_UpdateComponentStates(package,argument); + if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll )) + { + if (feature->ActionRequest != INSTALLSTATE_LOCAL) + msi_set_property( package->db, szPreselected, szOne ); + MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_LOCAL ); + } } return ERROR_SUCCESS; } -static UINT ControlEvent_Remove(MSIPACKAGE* package, LPCWSTR argument, - msi_dialog* dialog) +static UINT ControlEvent_Remove( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog ) { - MSIFEATURE *feature = NULL; + MSIFEATURE *feature; - if (lstrcmpW(szAll,argument)) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - MSI_SetFeatureStateW(package,argument,INSTALLSTATE_ABSENT); - } - else - { - LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) - msi_feature_set_state(package, feature, INSTALLSTATE_ABSENT); - - ACTION_UpdateComponentStates(package,argument); + if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll )) + { + if (feature->ActionRequest != INSTALLSTATE_ABSENT) + msi_set_property( package->db, szPreselected, szOne ); + MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_ABSENT ); + } } return ERROR_SUCCESS; } -static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument, - msi_dialog* dialog) +static UINT ControlEvent_AddSource( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog ) { - MSIFEATURE *feature = NULL; + MSIFEATURE *feature; - if (lstrcmpW(szAll,argument)) + LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - MSI_SetFeatureStateW(package,argument,INSTALLSTATE_SOURCE); - } - else - { - LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) - msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE); - ACTION_UpdateComponentStates(package,argument); + if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll )) + { + if (feature->ActionRequest != INSTALLSTATE_SOURCE) + msi_set_property( package->db, szPreselected, szOne ); + MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_SOURCE ); + } } return ERROR_SUCCESS; } @@ -284,10 +272,9 @@ VOID ControlEvent_FireSubscribedEvent( MSIPACKAGE *package, LPCWSTR event, LIST_FOR_EACH_ENTRY( sub, &package->subscriptions, struct subscriber, entry ) { - if (lstrcmpiW(sub->event, event)) + if (strcmpiW( sub->event, event )) continue; - msi_dialog_handle_event( sub->dialog, sub->control, - sub->attribute, rec ); + msi_dialog_handle_event( sub->dialog, sub->control, sub->attribute, rec ); } } @@ -300,7 +287,7 @@ VOID ControlEvent_CleanupDialogSubscriptions(MSIPACKAGE *package, LPWSTR dialog) { sub = LIST_ENTRY( i, struct subscriber, entry ); - if ( lstrcmpW( msi_dialog_get_name( sub->dialog ), dialog )) + if (strcmpW( msi_dialog_get_name( sub->dialog ), dialog )) continue; list_remove( &sub->entry ); @@ -441,7 +428,7 @@ UINT ControlEvent_HandleControlEvent(MSIPACKAGE *package, LPCWSTR event, while( Events[i].event != NULL) { LPWSTR wevent = strdupAtoW(Events[i].event); - if (lstrcmpW(wevent,event)==0) + if (!strcmpW( wevent, event )) { msi_free(wevent); rc = Events[i].handler(package,argument,dialog); diff --git a/reactos/dll/win32/msi/files.c b/reactos/dll/win32/msi/files.c index 0ed9582c179..1f6187356e1 100644 --- a/reactos/dll/win32/msi/files.c +++ b/reactos/dll/win32/msi/files.c @@ -60,21 +60,98 @@ static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *ac ui_progress( package, 2, f->FileSize, 0, 0 ); } +static msi_file_state calculate_install_state( MSIFILE *file ) +{ + MSICOMPONENT *comp = file->Component; + VS_FIXEDFILEINFO *file_version; + WCHAR *font_version; + msi_file_state state; + DWORD file_size; + + if (comp->ActionRequest != INSTALLSTATE_LOCAL || !comp->Enabled || + (comp->assembly && comp->assembly->installed)) + { + TRACE("file %s is not scheduled for install\n", debugstr_w(file->File)); + return msifs_skipped; + } + if ((comp->assembly && !comp->assembly->application && !comp->assembly->installed) || + GetFileAttributesW( file->TargetPath ) == INVALID_FILE_ATTRIBUTES) + { + TRACE("file %s is missing\n", debugstr_w(file->File)); + return msifs_missing; + } + if (file->Version) + { + if ((file_version = msi_get_disk_file_version( file->TargetPath ))) + { + TRACE("new %s old %u.%u.%u.%u\n", debugstr_w(file->Version), + HIWORD(file_version->dwFileVersionMS), + LOWORD(file_version->dwFileVersionMS), + HIWORD(file_version->dwFileVersionLS), + LOWORD(file_version->dwFileVersionLS)); + + if (msi_compare_file_versions( file_version, file->Version ) < 0) + state = msifs_overwrite; + else + { + TRACE("destination file version equal or greater, not overwriting\n"); + state = msifs_present; + } + msi_free( file_version ); + return state; + } + else if ((font_version = font_version_from_file( file->TargetPath ))) + { + TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(font_version)); + + if (msi_compare_font_versions( font_version, file->Version ) < 0) + state = msifs_overwrite; + else + { + TRACE("destination file version equal or greater, not overwriting\n"); + state = msifs_present; + } + msi_free( font_version ); + return state; + } + } + if ((file_size = msi_get_disk_file_size( file->TargetPath )) != file->FileSize) + { + return msifs_overwrite; + } + if (file->hash.dwFileHashInfoSize) + { + if (msi_file_hash_matches( file )) + { + TRACE("file hashes match, not overwriting\n"); + return msifs_hashmatch; + } + else + { + TRACE("file hashes do not match, overwriting\n"); + return msifs_overwrite; + } + } + /* assume present */ + return msifs_present; +} + static void schedule_install_files(MSIPACKAGE *package) { MSIFILE *file; LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry) { - if (file->Component->ActionRequest != INSTALLSTATE_LOCAL || !file->Component->Enabled) - { - TRACE("File %s is not scheduled for install\n", debugstr_w(file->File)); + MSICOMPONENT *comp = file->Component; - ui_progress(package,2,file->FileSize,0,0); + file->state = calculate_install_state( file ); + if (file->state == msifs_overwrite && (comp->Attributes & msidbComponentAttributesNeverOverwrite)) + { + TRACE("not overwriting %s\n", debugstr_w(file->TargetPath)); file->state = msifs_skipped; } - else - file->Component->Action = INSTALLSTATE_LOCAL; + comp->Action = INSTALLSTATE_LOCAL; + ui_progress( package, 2, file->FileSize, 0, 0 ); } } @@ -154,7 +231,7 @@ static UINT msi_create_directory( MSIPACKAGE *package, const WCHAR *dir ) MSIFOLDER *folder; WCHAR *install_path; - install_path = resolve_folder( package, dir, FALSE, FALSE, TRUE, &folder ); + install_path = resolve_target_folder( package, dir, FALSE, TRUE, &folder ); if (!install_path) return ERROR_FUNCTION_FAILED; @@ -178,7 +255,7 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, f = get_loaded_file(package, file); if (!f) { - WARN("unknown file in cabinet (%s)\n", debugstr_w(file)); + TRACE("unknown file in cabinet (%s)\n", debugstr_w(file)); return FALSE; } @@ -186,8 +263,10 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, return FALSE; msi_file_update_ui(package, f, szInstallFiles); - msi_create_directory(package, f->Component->Directory); - + if (!f->Component->assembly || f->Component->assembly->application) + { + msi_create_directory(package, f->Component->Directory); + } *path = strdupW(f->TargetPath); *attrs = f->Attributes; } @@ -210,6 +289,7 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, UINT ACTION_InstallFiles(MSIPACKAGE *package) { MSIMEDIAINFO *mi; + MSICOMPONENT *comp; UINT rc = ERROR_SUCCESS; MSIFILE *file; @@ -222,6 +302,20 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { + rc = msi_load_media_info( package, file, mi ); + if (rc != ERROR_SUCCESS) + { + ERR("Unable to load media info for %s (%u)\n", debugstr_w(file->File), rc); + return ERROR_FUNCTION_FAILED; + } + if (!file->Component->Enabled) continue; + + if (file->state != msifs_hashmatch && (rc = ready_media( package, file, mi ))) + { + ERR("Failed to ready media for %s\n", debugstr_w(file->File)); + goto done; + } + if (file->state != msifs_missing && !mi->is_continuous && file->state != msifs_overwrite) continue; @@ -230,13 +324,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) { MSICABDATA data; - rc = ready_media(package, file, mi); - if (rc != ERROR_SUCCESS) - { - ERR("Failed to ready media for %s\n", debugstr_w(file->File)); - break; - } - data.mi = mi; data.package = package; data.cb = installfiles_cb; @@ -247,7 +334,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) { ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet)); rc = ERROR_INSTALL_FAILURE; - break; + goto done; } } @@ -255,12 +342,13 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) { LPWSTR source = resolve_file_source(package, file); - TRACE("file paths %s to %s\n", debugstr_w(source), - debugstr_w(file->TargetPath)); + TRACE("copying %s to %s\n", debugstr_w(source), debugstr_w(file->TargetPath)); msi_file_update_ui(package, file, szInstallFiles); - msi_create_directory(package, file->Component->Directory); - + if (!file->Component->assembly || file->Component->assembly->application) + { + msi_create_directory(package, file->Component->Directory); + } rc = copy_install_file(package, file, source); if (rc != ERROR_SUCCESS) { @@ -268,19 +356,33 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) debugstr_w(file->TargetPath), rc); rc = ERROR_INSTALL_FAILURE; msi_free(source); - break; + goto done; } - msi_free(source); } else if (file->state != msifs_installed) { ERR("compressed file wasn't installed (%s)\n", debugstr_w(file->TargetPath)); rc = ERROR_INSTALL_FAILURE; - break; + goto done; + } + } + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + { + if (comp->ActionRequest == INSTALLSTATE_LOCAL && comp->Enabled && + comp->assembly && !comp->assembly->installed) + { + rc = install_assembly( package, comp ); + if (rc != ERROR_SUCCESS) + { + ERR("Failed to install assembly\n"); + rc = ERROR_INSTALL_FAILURE; + break; + } } } +done: msi_free_media_info(mi); return rc; } @@ -406,7 +508,7 @@ static BOOL add_wildcard(FILE_LIST *files, LPWSTR source, LPWSTR dest) LIST_FOR_EACH_ENTRY(file, &files->entry, FILE_LIST, entry) { - if (lstrcmpW(source, file->source) < 0) + if (strcmpW( source, file->source ) < 0) { list_add_before(&file->entry, &new->entry); return TRUE; @@ -663,7 +765,7 @@ static WCHAR *get_duplicate_filename( MSIPACKAGE *package, MSIRECORD *row, const { const WCHAR *dst_key = MSI_RecordGetString( row, 5 ); - dst_path = resolve_folder( package, dst_key, FALSE, FALSE, TRUE, NULL ); + dst_path = resolve_target_folder( package, dst_key, FALSE, TRUE, NULL ); if (!dst_path) { /* try a property */ @@ -861,25 +963,25 @@ static BOOL verify_comp_for_removal(MSICOMPONENT *comp, UINT install_mode) { INSTALLSTATE request = comp->ActionRequest; - if (request == INSTALLSTATE_UNKNOWN) - return FALSE; + /* special case */ + if (request != INSTALLSTATE_SOURCE && + comp->Attributes & msidbComponentAttributesSourceOnly && + (install_mode == msidbRemoveFileInstallModeOnRemove || + install_mode == msidbRemoveFileInstallModeOnBoth)) return TRUE; - if (install_mode == msidbRemoveFileInstallModeOnInstall && - (request == INSTALLSTATE_LOCAL || request == INSTALLSTATE_SOURCE)) - return TRUE; - - if (request == INSTALLSTATE_ABSENT) + switch (request) { - if (!comp->ComponentId) - return FALSE; - - if (install_mode == msidbRemoveFileInstallModeOnRemove) - return TRUE; + case INSTALLSTATE_LOCAL: + case INSTALLSTATE_SOURCE: + if (install_mode == msidbRemoveFileInstallModeOnInstall || + install_mode == msidbRemoveFileInstallModeOnBoth) return TRUE; + break; + case INSTALLSTATE_ABSENT: + if (install_mode == msidbRemoveFileInstallModeOnRemove || + install_mode == msidbRemoveFileInstallModeOnBoth) return TRUE; + break; + default: break; } - - if (install_mode == msidbRemoveFileInstallModeOnBoth) - return TRUE; - return FALSE; } @@ -888,24 +990,17 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) MSIPACKAGE *package = param; MSICOMPONENT *comp; MSIRECORD *uirow; - LPCWSTR component, filename, dirprop; + LPCWSTR component, dirprop; UINT install_mode; - LPWSTR dir = NULL, path = NULL; + LPWSTR dir = NULL, path = NULL, filename = NULL; DWORD size; UINT ret = ERROR_SUCCESS; component = MSI_RecordGetString(row, 2); - filename = MSI_RecordGetString(row, 3); dirprop = MSI_RecordGetString(row, 4); install_mode = MSI_RecordGetInteger(row, 5); comp = get_loaded_component(package, component); - if (!comp) - { - ERR("Invalid component: %s\n", debugstr_w(component)); - return ERROR_FUNCTION_FAILED; - } - if (!comp->Enabled) { TRACE("component is disabled\n"); @@ -914,16 +1009,27 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) if (!verify_comp_for_removal(comp, install_mode)) { - TRACE("Skipping removal due to missing conditions\n"); + TRACE("Skipping removal due to install mode\n"); comp->Action = comp->Installed; return ERROR_SUCCESS; } + if (comp->Attributes & msidbComponentAttributesPermanent) + { + TRACE("permanent component, not removing file\n"); + return ERROR_SUCCESS; + } + dir = msi_dup_property(package->db, dirprop); if (!dir) return ERROR_OUTOFMEMORY; - size = (filename != NULL) ? lstrlenW(filename) : 0; + size = 0; + if ((filename = strdupW( MSI_RecordGetString(row, 3) ))) + { + reduce_to_longfilename( filename ); + size = lstrlenW( filename ); + } size += lstrlenW(dir) + 2; path = msi_alloc(size * sizeof(WCHAR)); if (!path) @@ -954,11 +1060,39 @@ done: ui_actiondata( package, szRemoveFiles, uirow ); msiobj_release( &uirow->hdr ); + msi_free(filename); msi_free(path); msi_free(dir); return ret; } +static BOOL has_persistent_dir( MSIPACKAGE *package, MSICOMPONENT *comp ) +{ + MSIQUERY *view; + UINT r = ERROR_FUNCTION_FAILED; + + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','C','r','e','a','t','e','F','o','l','d','e','r','`',' ','W','H','E','R','E',' ', + '`','C','o','m','p','o','n','e','n','t','_','`',' ','=','\'','%','s','\'',' ','A','N','D',' ', + '`','D','i','r','e','c','t','o','r','y','_','`',' ','=','\'','%','s','\'',0}; + + if (!MSI_OpenQuery( package->db, &view, query, comp->Component, comp->Directory )) + { + if (!MSI_ViewExecute( view, NULL )) + { + MSIRECORD *rec; + if (!(r = MSI_ViewFetch( view, &rec ))) + { + TRACE("directory %s is persistent\n", debugstr_w(comp->Directory)); + msiobj_release( &rec->hdr ); + } + } + msiobj_release( &view->hdr ); + } + return (r == ERROR_SUCCESS); +} + UINT ACTION_RemoveFiles( MSIPACKAGE *package ) { MSIQUERY *view; @@ -968,9 +1102,6 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', '`','R','e','m','o','v','e','F','i','l','e','`',0}; - static const WCHAR folder_query[] = { - 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0}; r = MSI_DatabaseOpenViewW(package->db, query, &view); if (r == ERROR_SUCCESS) @@ -979,10 +1110,6 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) msiobj_release(&view->hdr); } - r = MSI_DatabaseOpenViewW(package->db, folder_query, &view); - if (r == ERROR_SUCCESS) - msiobj_release(&view->hdr); - LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { MSIRECORD *uirow; @@ -1002,6 +1129,12 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) continue; } + if (file->Component->Attributes & msidbComponentAttributesPermanent) + { + TRACE("permanent component, not removing file\n"); + continue; + } + if (file->Version) { ver = msi_get_disk_file_version( file->TargetPath ); @@ -1015,16 +1148,20 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) } TRACE("removing %s\n", debugstr_w(file->File) ); + + SetFileAttributesW( file->TargetPath, FILE_ATTRIBUTE_NORMAL ); if (!DeleteFileW( file->TargetPath )) { - WARN("failed to delete %s\n", debugstr_w(file->TargetPath)); + WARN("failed to delete %s (%u)\n", debugstr_w(file->TargetPath), GetLastError()); } - /* FIXME: check persistence for each directory */ - else if (r && (dir = strdupW( file->TargetPath ))) + else if (!has_persistent_dir( package, file->Component )) { - if ((p = strrchrW( dir, '\\' ))) *p = 0; - RemoveDirectoryW( dir ); - msi_free( dir ); + if ((dir = strdupW( file->TargetPath ))) + { + if ((p = strrchrW( dir, '\\' ))) *p = 0; + RemoveDirectoryW( dir ); + msi_free( dir ); + } } file->state = msifs_missing; diff --git a/reactos/dll/win32/msi/font.c b/reactos/dll/win32/msi/font.c index 2128e922a56..7a493867c6a 100644 --- a/reactos/dll/win32/msi/font.c +++ b/reactos/dll/win32/msi/font.c @@ -52,6 +52,9 @@ typedef struct _tagTT_NAME_TABLE_HEADER { * from start of the table */ } TT_NAME_TABLE_HEADER; +#define NAME_ID_FULL_FONT_NAME 4 +#define NAME_ID_VERSION 5 + typedef struct _tagTT_NAME_RECORD { USHORT uPlatformID; USHORT uEncodingID; @@ -80,10 +83,8 @@ static const WCHAR regfont2[] = /* * Code based off of code located here * http://www.codeproject.com/gdi/fontnamefromfile.asp - * - * Using string index 4 (full font name) instead of 1 (family name) */ -static LPWSTR load_ttfname_from(LPCWSTR filename) +WCHAR *load_ttf_name_id( const WCHAR *filename, DWORD id ) { TT_TABLE_DIRECTORY tblDir; BOOL bFound = FALSE; @@ -142,30 +143,24 @@ static LPWSTR load_ttfname_from(LPCWSTR filename) break; ttRecord.uNameID = SWAPWORD(ttRecord.uNameID); - /* 4 is the Full Font Name */ - if(ttRecord.uNameID == 4) + if (ttRecord.uNameID == id) { int nPos; LPSTR buf; - static const char tt[] = " (TrueType)"; ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength); ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset); nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT); - SetFilePointer(handle, tblDir.uOffset + - ttRecord.uStringOffset + - ttNTHeader.uStorageOffset, - NULL, FILE_BEGIN); - buf = msi_alloc_zero( ttRecord.uStringLength + 1 + strlen(tt) ); + SetFilePointer(handle, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, + NULL, FILE_BEGIN); + buf = msi_alloc_zero( ttRecord.uStringLength + 1 ); ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL); if (strlen(buf) > 0) { - strcat(buf,tt); ret = strdupAtoW(buf); msi_free(buf); break; } - msi_free(buf); SetFilePointer(handle,nPos, NULL, FILE_BEGIN); } @@ -173,8 +168,36 @@ static LPWSTR load_ttfname_from(LPCWSTR filename) end: CloseHandle(handle); + TRACE("Returning %s\n", debugstr_w(ret)); + return ret; +} - TRACE("Returning fontname %s\n",debugstr_w(ret)); +static WCHAR *font_name_from_file( const WCHAR *filename ) +{ + static const WCHAR truetypeW[] = {' ','(','T','r','u','e','T','y','p','e',')',0}; + WCHAR *name, *ret = NULL; + + if ((name = load_ttf_name_id( filename, NAME_ID_FULL_FONT_NAME ))) + { + ret = msi_alloc( (strlenW( name ) + strlenW( truetypeW ) + 1 ) * sizeof(WCHAR) ); + strcpyW( ret, name ); + strcatW( ret, truetypeW ); + msi_free( name ); + } + return ret; +} + +WCHAR *font_version_from_file( const WCHAR *filename ) +{ + WCHAR *version, *p, *ret = NULL; + + if ((p = version = load_ttf_name_id( filename, NAME_ID_VERSION ))) + { + while (*p && !isdigitW( *p )) p++; + ret = msi_alloc( (strlenW( p ) + 1) * sizeof(WCHAR) ); + strcpyW( ret, p ); + msi_free( version ); + } return ret; } @@ -212,7 +235,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); if (MSI_RecordIsNull(row,2)) - name = load_ttfname_from( file->TargetPath ); + name = font_name_from_file( file->TargetPath ); else name = msi_dup_record_field(row,2); @@ -296,7 +319,7 @@ static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param ) RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 ); if (MSI_RecordIsNull( row, 2 )) - name = load_ttfname_from( file->TargetPath ); + name = font_name_from_file( file->TargetPath ); else name = msi_dup_record_field( row, 2 ); diff --git a/reactos/dll/win32/msi/format.c b/reactos/dll/win32/msi/format.c index c4ff30f4111..b970dc1479f 100644 --- a/reactos/dll/win32/msi/format.c +++ b/reactos/dll/win32/msi/format.c @@ -185,7 +185,6 @@ static LPWSTR deformat_component(FORMAT *format, FORMSTR *str) { LPWSTR key, ret = NULL; MSICOMPONENT *comp; - BOOL source; key = msi_alloc((str->len + 1) * sizeof(WCHAR)); lstrcpynW(key, get_formstr_data(format, str), str->len + 1); @@ -194,8 +193,10 @@ static LPWSTR deformat_component(FORMAT *format, FORMSTR *str) if (!comp) goto done; - source = (comp->Action == INSTALLSTATE_SOURCE) ? TRUE : FALSE; - ret = resolve_folder(format->package, comp->Directory, source, FALSE, TRUE, NULL); + if (comp->Action == INSTALLSTATE_SOURCE) + ret = resolve_source_folder( format->package, comp->Directory, NULL ); + else + ret = resolve_target_folder( format->package, comp->Directory, FALSE, TRUE, NULL ); done: msi_free(key); diff --git a/reactos/dll/win32/msi/helpers.c b/reactos/dll/win32/msi/helpers.c index d3f2d9074a5..ffbe58b40e0 100644 --- a/reactos/dll/win32/msi/helpers.c +++ b/reactos/dll/win32/msi/helpers.c @@ -104,7 +104,7 @@ MSICOMPONENT* get_loaded_component( MSIPACKAGE* package, LPCWSTR Component ) LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) { - if (lstrcmpW(Component,comp->Component)==0) + if (!strcmpW( Component, comp->Component )) return comp; } return NULL; @@ -116,7 +116,7 @@ MSIFEATURE* get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature ) LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - if (lstrcmpW( Feature, feature->Feature )==0) + if (!strcmpW( Feature, feature->Feature )) return feature; } return NULL; @@ -128,7 +128,7 @@ MSIFILE* get_loaded_file( MSIPACKAGE* package, LPCWSTR key ) LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { - if (lstrcmpW( key, file->File )==0) + if (!strcmpW( key, file->File )) return file; } return NULL; @@ -141,7 +141,7 @@ int track_tempfile( MSIPACKAGE *package, LPCWSTR path ) TRACE("%s\n", debugstr_w(path)); LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry ) - if (!lstrcmpW( path, temp->Path )) + if (!strcmpW( path, temp->Path )) return 0; temp = msi_alloc_zero( sizeof (MSITEMPFILE) ); @@ -160,7 +160,7 @@ MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir ) LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry ) { - if (lstrcmpW( dir, folder->Directory )==0) + if (!strcmpW( dir, folder->Directory )) return folder; } return NULL; @@ -232,8 +232,7 @@ LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file) if (file->IsCompressed) return NULL; - p = resolve_folder(package, file->Component->Directory, - TRUE, FALSE, TRUE, NULL); + p = resolve_source_folder( package, file->Component->Directory, NULL ); path = build_directory_name(2, p, file->ShortName); if (file->LongName && @@ -245,24 +244,18 @@ LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file) msi_free(p); - TRACE("file %s source resolves to %s\n", debugstr_w(file->File), - debugstr_w(path)); - + TRACE("file %s source resolves to %s\n", debugstr_w(file->File), debugstr_w(path)); return path; } -LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, - BOOL set_prop, BOOL load_prop, MSIFOLDER **folder) +LPWSTR resolve_source_folder( MSIPACKAGE *package, LPCWSTR name, MSIFOLDER **folder ) { MSIFOLDER *f; LPWSTR p, path = NULL, parent; - TRACE("Working to resolve %s\n",debugstr_w(name)); + TRACE("working to resolve %s\n", debugstr_w(name)); - if (!name) - return NULL; - - if (!lstrcmpW(name,cszSourceDir)) + if (!strcmpW( name, cszSourceDir )) name = cszTargetDir; f = get_loaded_folder( package, name ); @@ -270,7 +263,58 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, return NULL; /* special resolving for Target and Source root dir */ - if (!strcmpW(name,cszTargetDir)) + if (!strcmpW( name, cszTargetDir )) + { + if (!f->ResolvedSource) + f->ResolvedSource = get_source_root( package ); + } + + if (folder) + *folder = f; + + if (f->ResolvedSource) + { + path = strdupW( f->ResolvedSource ); + TRACE(" already resolved to %s\n", debugstr_w(path)); + return path; + } + + if (!f->Parent) + return path; + + parent = f->Parent; + TRACE(" ! parent is %s\n", debugstr_w(parent)); + + p = resolve_source_folder( package, parent, NULL ); + + if (package->WordCount & msidbSumInfoSourceTypeCompressed) + path = get_source_root( package ); + else if (package->WordCount & msidbSumInfoSourceTypeSFN) + path = build_directory_name( 3, p, f->SourceShortPath, NULL ); + else + path = build_directory_name( 3, p, f->SourceLongPath, NULL ); + + TRACE("-> %s\n", debugstr_w(path)); + f->ResolvedSource = strdupW( path ); + msi_free( p ); + + return path; +} + +LPWSTR resolve_target_folder( MSIPACKAGE *package, LPCWSTR name, BOOL set_prop, BOOL load_prop, + MSIFOLDER **folder ) +{ + MSIFOLDER *f; + LPWSTR p, path = NULL, parent; + + TRACE("working to resolve %s\n", debugstr_w(name)); + + f = get_loaded_folder( package, name ); + if (!f) + return NULL; + + /* special resolving for Target and Source root dir */ + if (!strcmpW( name, cszTargetDir )) { if (!f->ResolvedTarget && !f->Property) { @@ -286,45 +330,33 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, /* correct misbuilt target dir */ path = build_directory_name(2, check_path, NULL); clean_spaces_from_path( path ); - if (strcmpiW(path,check_path)!=0) + if (strcmpiW( path, check_path )) msi_set_property( package->db, cszTargetDir, path ); msi_free(check_path); f->ResolvedTarget = path; } - - if (!f->ResolvedSource) - f->ResolvedSource = get_source_root( package ); } if (folder) *folder = f; - if (!source && f->ResolvedTarget) + if (f->ResolvedTarget) { path = strdupW( f->ResolvedTarget ); - TRACE(" already resolved to %s\n",debugstr_w(path)); + TRACE(" already resolved to %s\n", debugstr_w(path)); return path; } - if (source && f->ResolvedSource) - { - path = strdupW( f->ResolvedSource ); - TRACE(" (source)already resolved to %s\n",debugstr_w(path)); - return path; - } - - if (!source && f->Property) + if (f->Property) { path = build_directory_name( 2, f->Property, NULL ); - - TRACE(" internally set to %s\n",debugstr_w(path)); - if (set_prop) - msi_set_property( package->db, name, path ); + TRACE(" internally set to %s\n", debugstr_w(path)); + if (set_prop) msi_set_property( package->db, name, path ); return path; } - if (!source && load_prop && (path = msi_dup_property( package->db, name ))) + if (load_prop && (path = msi_dup_property( package->db, name ))) { f->ResolvedTarget = strdupW( path ); TRACE(" property set to %s\n", debugstr_w(path)); @@ -336,35 +368,18 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, parent = f->Parent; - TRACE(" ! Parent is %s\n", debugstr_w(parent)); + TRACE(" ! parent is %s\n", debugstr_w(parent)); - p = resolve_folder(package, parent, source, set_prop, load_prop, NULL); - if (!source) - { - TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault)); + p = resolve_target_folder( package, parent, set_prop, load_prop, NULL ); - path = build_directory_name( 3, p, f->TargetDefault, NULL ); - clean_spaces_from_path( path ); - f->ResolvedTarget = strdupW( path ); - TRACE("target -> %s\n", debugstr_w(path)); - if (set_prop) - msi_set_property( package->db, name, path ); - } - else - { - path = NULL; + TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault)); + path = build_directory_name( 3, p, f->TargetDefault, NULL ); + clean_spaces_from_path( path ); + f->ResolvedTarget = strdupW( path ); - if (package->WordCount & msidbSumInfoSourceTypeCompressed) - path = get_source_root( package ); - else if (package->WordCount & msidbSumInfoSourceTypeSFN) - path = build_directory_name( 3, p, f->SourceShortPath, NULL ); - else - path = build_directory_name( 3, p, f->SourceLongPath, NULL ); - - TRACE("source -> %s\n", debugstr_w(path)); - f->ResolvedSource = strdupW( path ); - } - msi_free(p); + TRACE("-> %s\n", debugstr_w(path)); + if (set_prop) msi_set_property( package->db, name, path ); + msi_free( p ); return path; } @@ -479,6 +494,8 @@ LPWSTR build_directory_name(DWORD count, ...) if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\') strcatW(dir, szBackSlash); } + va_end(va); + return dir; } @@ -561,7 +578,7 @@ void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record) MSIRECORD * row = 0; DWORD size; - if (!package->LastAction || strcmpW(package->LastAction,action)) + if (!package->LastAction || strcmpW(package->LastAction, action)) { row = MSI_QueryGetRecord(package->db, Query_t, action); if (!row) @@ -639,16 +656,11 @@ LPWSTR create_component_advertise_string(MSIPACKAGE* package, } /* update component state based on a feature change */ -void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature) +void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature ) { INSTALLSTATE newstate; - MSIFEATURE *feature; ComponentList *cl; - feature = get_loaded_feature(package,szFeature); - if (!feature) - return; - newstate = feature->ActionRequest; if (newstate == INSTALLSTATE_ABSENT) @@ -658,15 +670,17 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature) { MSICOMPONENT* component = cl->component; + if (!component->Enabled) continue; + TRACE("MODIFYING(%i): Component %s (Installed %i, Action %i, Request %i)\n", newstate, debugstr_w(component->Component), component->Installed, component->Action, component->ActionRequest); - if (!component->Enabled) - continue; - if (newstate == INSTALLSTATE_LOCAL) - msi_component_set_state(package, component, INSTALLSTATE_LOCAL); + { + component->Action = INSTALLSTATE_LOCAL; + component->ActionRequest = INSTALLSTATE_LOCAL; + } else { ComponentList *clist; @@ -674,9 +688,10 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature) component->hasLocalFeature = FALSE; - msi_component_set_state(package, component, newstate); + component->Action = newstate; + component->ActionRequest = newstate; - /*if any other feature wants is local we need to set it local*/ + /* if any other feature wants it local we need to set it local */ LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry ) { if ( f->ActionRequest != INSTALLSTATE_LOCAL && @@ -697,14 +712,26 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature) if (component->Attributes & msidbComponentAttributesOptional) { if (f->Attributes & msidbFeatureAttributesFavorSource) - msi_component_set_state(package, component, INSTALLSTATE_SOURCE); + { + component->Action = INSTALLSTATE_SOURCE; + component->ActionRequest = INSTALLSTATE_SOURCE; + } else - msi_component_set_state(package, component, INSTALLSTATE_LOCAL); + { + component->Action = INSTALLSTATE_LOCAL; + component->ActionRequest = INSTALLSTATE_LOCAL; + } } else if (component->Attributes & msidbComponentAttributesSourceOnly) - msi_component_set_state(package, component, INSTALLSTATE_SOURCE); + { + component->Action = INSTALLSTATE_SOURCE; + component->ActionRequest = INSTALLSTATE_SOURCE; + } else - msi_component_set_state(package, component, INSTALLSTATE_LOCAL); + { + component->Action = INSTALLSTATE_LOCAL; + component->ActionRequest = INSTALLSTATE_LOCAL; + } } } } @@ -747,7 +774,7 @@ BOOL check_unique_action(const MSIPACKAGE *package, LPCWSTR action) return FALSE; for (i = 0; i < package->script->UniqueActionsCount; i++) - if (!strcmpW(package->script->UniqueActions[i],action)) + if (!strcmpW(package->script->UniqueActions[i], action)) return TRUE; return FALSE; diff --git a/reactos/dll/win32/msi/insert.c b/reactos/dll/win32/msi/insert.c index 61807e9534e..03e1bd99795 100644 --- a/reactos/dll/win32/msi/insert.c +++ b/reactos/dll/win32/msi/insert.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winerror.h" #include "wine/debug.h" +#include "wine/unicode.h" #include "msi.h" #include "msiquery.h" #include "objbase.h" @@ -117,7 +118,7 @@ static BOOL msi_columns_in_order(MSIINSERTVIEW *iv, UINT col_count) iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL, NULL); iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL, NULL); - res = lstrcmpW(a, b); + res = strcmpW( a, b ); msi_free(a); msi_free(b); @@ -168,7 +169,7 @@ static UINT msi_arrange_record(MSIINSERTVIEW *iv, MSIRECORD **values) if (r != ERROR_SUCCESS) goto err; - res = lstrcmpW(a, b); + res = strcmpW( a, b ); msi_free(b); if (res == 0) diff --git a/reactos/dll/win32/msi/install.c b/reactos/dll/win32/msi/install.c index fa3e4f9e382..30a63e6d8bb 100644 --- a/reactos/dll/win32/msi/install.c +++ b/reactos/dll/win32/msi/install.c @@ -282,7 +282,7 @@ done: return r; } - path = resolve_folder( package, szFolder, FALSE, FALSE, TRUE, NULL ); + path = resolve_target_folder( package, szFolder, FALSE, TRUE, NULL ); msiobj_release( &package->hdr ); if (!path) @@ -336,7 +336,7 @@ UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, } /*********************************************************************** - * MsiGetSourcePath (internal) + * MSI_GetSourcePath (internal) */ static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder, awstring *szPathBuf, LPDWORD pcchPathBuf ) @@ -413,10 +413,10 @@ done: return ERROR_INVALID_PARAMETER; } - path = resolve_folder(package, szFolder, TRUE, FALSE, TRUE, NULL); + path = resolve_source_folder( package, szFolder, NULL ); msiobj_release( &package->hdr ); - TRACE("path = %s\n",debugstr_w(path)); + TRACE("path = %s\n", debugstr_w(path)); if (!path) return ERROR_DIRECTORY; @@ -512,14 +512,14 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, attrib & FILE_ATTRIBUTE_READONLY)) return ERROR_FUNCTION_FAILED; - path = resolve_folder(package,szFolder,FALSE,FALSE,FALSE,&folder); + path = resolve_target_folder( package, szFolder, FALSE, FALSE, &folder ); if (!path) return ERROR_DIRECTORY; msi_free(folder->Property); folder->Property = build_directory_name(2, szFolderPath, NULL); - if (lstrcmpiW(path, folder->Property) == 0) + if (!strcmpiW( path, folder->Property )) { /* * Resolved Target has not really changed, so just @@ -527,7 +527,7 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, */ msi_free(folder->ResolvedTarget); folder->ResolvedTarget = NULL; - path2 = resolve_folder(package,szFolder,FALSE,TRUE,FALSE,NULL); + path2 = resolve_target_folder( package, szFolder, TRUE, FALSE, NULL ); msi_free(path2); } else @@ -542,23 +542,23 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry ) { - path2 = resolve_folder(package, f->Directory, FALSE, TRUE, FALSE, NULL); + path2 = resolve_target_folder( package, f->Directory, TRUE, FALSE, NULL ); msi_free(path2); } LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { MSICOMPONENT *comp = file->Component; - LPWSTR p; + LPWSTR dir; - if (!comp) + if (!comp->Enabled || (comp->assembly && !comp->assembly->application)) continue; - p = resolve_folder(package, comp->Directory, FALSE, FALSE, FALSE, NULL); + dir = resolve_target_folder( package, comp->Directory, FALSE, FALSE, NULL ); msi_free(file->TargetPath); - file->TargetPath = build_directory_name(2, p, file->FileName); - msi_free(p); + file->TargetPath = build_directory_name(2, dir, file->FileName); + msi_free(dir); } } msi_free(path); @@ -716,6 +716,10 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode) r = package->need_reboot; break; + case MSIRUNMODE_LOGENABLED: + r = (package->log_file != INVALID_HANDLE_VALUE); + break; + default: FIXME("unimplemented run mode: %d\n", iRunMode); r = TRUE; @@ -821,14 +825,14 @@ UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature, feature->Attributes & msidbFeatureAttributesDisallowAdvertise) return ERROR_FUNCTION_FAILED; - msi_feature_set_state(package, feature, iState); + feature->ActionRequest = iState; - ACTION_UpdateComponentStates(package,szFeature); + ACTION_UpdateComponentStates( package, feature ); /* update all the features that are children of this feature */ LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry ) { - if (lstrcmpW(szFeature, child->Feature_Parent) == 0) + if (child->Feature_Parent && !strcmpW( szFeature, child->Feature_Parent )) MSI_SetFeatureStateW(package, child->Feature, iState); } @@ -917,9 +921,9 @@ UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature, *piInstalled = feature->Installed; if (piAction) - *piAction = feature->Action; + *piAction = feature->ActionRequest; - TRACE("returning %i %i\n", feature->Installed, feature->Action); + TRACE("returning %i %i\n", feature->Installed, feature->ActionRequest); return ERROR_SUCCESS; } @@ -1158,7 +1162,8 @@ static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent, if (!comp) return ERROR_UNKNOWN_COMPONENT; - comp->Installed = iState; + if (comp->Enabled) + comp->Action = iState; return ERROR_SUCCESS; } @@ -1176,13 +1181,22 @@ UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent, return ERROR_UNKNOWN_COMPONENT; if (piInstalled) - *piInstalled = comp->Installed; + { + if (comp->Enabled) + *piInstalled = comp->Installed; + else + *piInstalled = INSTALLSTATE_UNKNOWN; + } if (piAction) - *piAction = comp->Action; + { + if (comp->Enabled) + *piAction = comp->Action; + else + *piAction = INSTALLSTATE_UNKNOWN; + } TRACE("states (%i, %i)\n", comp->Installed, comp->Action ); - return ERROR_SUCCESS; } diff --git a/reactos/dll/win32/msi/media.c b/reactos/dll/win32/msi/media.c index 788528e9b37..37d353017e1 100644 --- a/reactos/dll/win32/msi/media.c +++ b/reactos/dll/win32/msi/media.c @@ -68,7 +68,7 @@ static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root) return FALSE; } - return !lstrcmpW(mi->volume_label, volume_name); + return !strcmpW( mi->volume_label, volume_name ); } static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi) @@ -331,7 +331,7 @@ static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, goto done; } - if (lstrcmpiW(mi->cabinet, cab)) + if (strcmpiW( mi->cabinet, cab )) { ERR("Continuous cabinet does not match the next cabinet in the Media table\n"); goto done; @@ -656,7 +656,7 @@ static UINT get_drive_type(const WCHAR *path) return GetDriveTypeW(root); } -static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) +UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) { MSIRECORD *row; LPWSTR source_dir; @@ -748,23 +748,44 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) if (r != ERROR_SUCCESS) return r; - index = 0; - volumesz = MAX_PATH; - promptsz = MAX_PATH; - if (last_type[0] == 'n') { - while (MsiSourceListEnumSourcesW(package->ProductCode, NULL, - package->Context, - MSISOURCETYPE_NETWORK, index++, - volume, &volumesz) == ERROR_SUCCESS) + WCHAR cabinet_file[MAX_PATH]; + BOOL check_all = FALSE; + + while(TRUE) { - if (!strncmpiW(source, volume, strlenW(source))) + index = 0; + volumesz = MAX_PATH; + while (MsiSourceListEnumSourcesW(package->ProductCode, NULL, + package->Context, + MSISOURCETYPE_NETWORK, index++, + volume, &volumesz) == ERROR_SUCCESS) { - lstrcpyW(mi->sourcedir, source); - TRACE("Found network source %s\n", debugstr_w(mi->sourcedir)); - return ERROR_SUCCESS; + if (check_all || !strncmpiW(source, volume, strlenW(source))) + { + lstrcpyW(cabinet_file, volume); + PathAddBackslashW(cabinet_file); + lstrcatW(cabinet_file, mi->cabinet); + + if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES) + { + volumesz = MAX_PATH; + if(!check_all) + break; + continue; + } + + lstrcpyW(mi->sourcedir, volume); + TRACE("Found network source %s\n", debugstr_w(mi->sourcedir)); + return ERROR_SUCCESS; + } } + + if (!check_all) + check_all = TRUE; + else + break; } } @@ -803,13 +824,6 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) if (mi->is_continuous) return ERROR_SUCCESS; - rc = msi_load_media_info(package, file, mi); - if (rc != ERROR_SUCCESS) - { - ERR("Unable to load media info %u\n", rc); - return ERROR_FUNCTION_FAILED; - } - /* cabinet is internal, no checks needed */ if (!mi->cabinet || mi->cabinet[0] == '#') return ERROR_SUCCESS; @@ -841,7 +855,7 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) /* check volume matches, change media if not */ if (mi->volume_label && mi->disk_id > 1 && - lstrcmpW(mi->first_volume, mi->volume_label)) + strcmpW( mi->first_volume, mi->volume_label )) { LPWSTR source = msi_dup_property(package->db, cszSourceDir); BOOL matches; diff --git a/reactos/dll/win32/msi/msi.c b/reactos/dll/win32/msi/msi.c index 7d1b9a55095..325a5b04634 100644 --- a/reactos/dll/win32/msi/msi.c +++ b/reactos/dll/win32/msi/msi.c @@ -299,13 +299,14 @@ done: return r; } -static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR **product_codes ) + +static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR ***product_codes ) { MSIHANDLE patch, info = 0; UINT r, type; DWORD size; static WCHAR empty[] = {0}; - WCHAR *codes; + WCHAR *codes = NULL; r = MsiOpenDatabaseW( szPatchPackage, MSIDBOPEN_READONLY, &patch ); if (r != ERROR_SUCCESS) @@ -332,26 +333,25 @@ static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR **product_cod } r = MsiSummaryInfoGetPropertyW( info, PID_TEMPLATE, &type, NULL, NULL, codes, &size ); - if (r != ERROR_SUCCESS) - msi_free( codes ); - else - *product_codes = codes; + if (r == ERROR_SUCCESS) + *product_codes = msi_split_string( codes, ';' ); done: MsiCloseHandle( info ); MsiCloseHandle( patch ); + msi_free( codes ); return r; } static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWSTR szCommandLine) { - UINT r; + UINT r, i; DWORD size; LPCWSTR cmd_ptr = szCommandLine; - LPWSTR beg, end, cmd, codes = NULL; + LPWSTR cmd, *codes = NULL; BOOL succeeded = FALSE; - static const WCHAR patcheq[] = {'P','A','T','C','H','=',0}; + static const WCHAR fmt[] = {'%','s',' ','P','A','T','C','H','=','"','%','s','"',0}; static WCHAR empty[] = {0}; if (!szPatchPackage || !szPatchPackage[0]) @@ -363,34 +363,27 @@ static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWS if (!szCommandLine) cmd_ptr = empty; - size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1; + size = strlenW(cmd_ptr) + strlenW(fmt) + strlenW(szPatchPackage) + 1; cmd = msi_alloc(size * sizeof(WCHAR)); if (!cmd) { msi_free(codes); return ERROR_OUTOFMEMORY; } - - lstrcpyW(cmd, cmd_ptr); - if (szCommandLine) lstrcatW(cmd, szSpace); - lstrcatW(cmd, patcheq); - lstrcatW(cmd, szPatchPackage); + sprintfW(cmd, fmt, cmd_ptr, szPatchPackage); if (szProductCode) r = MsiConfigureProductExW(szProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); else { - beg = codes; - while ((end = strchrW(beg, '}'))) + for (i = 0; codes[i]; i++) { - *(end + 1) = '\0'; - r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); + r = MsiConfigureProductExW(codes[i], INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); if (r == ERROR_SUCCESS) { TRACE("patch applied\n"); succeeded = TRUE; } - beg = end + 2; } if (succeeded) @@ -688,6 +681,8 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, static const WCHAR szInstalled[] = { ' ','I','n','s','t','a','l','l','e','d','=','1',0}; + static const WCHAR szInstallLevel[] = { + ' ','I','N','S','T','A','L','L','L','E','V','E','L','=','3','2','7','6','7',0}; static const WCHAR szRemoveAll[] = { ' ','R','E','M','O','V','E','=','A','L','L',0}; static const WCHAR szMachine[] = { @@ -719,6 +714,9 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, if (szCommandLine) sz += lstrlenW(szCommandLine); + if (eInstallState != INSTALLSTATE_DEFAULT) + sz += lstrlenW(szInstallLevel); + if (eInstallState == INSTALLSTATE_ABSENT) sz += lstrlenW(szRemoveAll); @@ -736,6 +734,9 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, if (szCommandLine) lstrcpyW(commandline,szCommandLine); + if (eInstallState != INSTALLSTATE_DEFAULT) + lstrcatW(commandline, szInstallLevel); + if (eInstallState == INSTALLSTATE_ABSENT) lstrcatW(commandline, szRemoveAll); @@ -983,22 +984,22 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE); - if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW)) + if (!strcmpW( szAttribute, INSTALLPROPERTY_HELPLINKW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_HELPTELEPHONEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_INSTALLDATEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_INSTALLSOURCEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_LOCALPACKAGEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_PUBLISHERW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_URLINFOABOUTW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_URLUPDATEINFOW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_VERSIONMINORW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_VERSIONMAJORW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTIDW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_REGCOMPANYW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_REGOWNERW )) { if (!prodkey) { @@ -1009,25 +1010,25 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, if (!userdata) return ERROR_UNKNOWN_PROPERTY; - if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW)) + if (!strcmpW( szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW )) szAttribute = display_name; - else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW)) + else if (!strcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW )) szAttribute = display_version; val = msi_reg_get_value(userdata, szAttribute, &type); if (!val) val = empty; } - else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) || - !lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW)) + else if (!strcmpW( szAttribute, INSTALLPROPERTY_INSTANCETYPEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_TRANSFORMSW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_LANGUAGEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTNAMEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_PACKAGECODEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_VERSIONW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTICONW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_PACKAGENAMEW ) || + !strcmpW( szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW )) { if (!prodkey) { @@ -1035,10 +1036,10 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, goto done; } - if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW)) + if (!strcmpW( szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW )) szAttribute = assignment; - if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW)) + if (!strcmpW( szAttribute, INSTALLPROPERTY_PACKAGENAMEW )) { res = RegOpenKeyW(prodkey, sourcelist, &source); if (res != ERROR_SUCCESS) @@ -1061,7 +1062,7 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, } if (val != empty && type != REG_DWORD && - !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW)) + !strcmpW( szAttribute, INSTALLPROPERTY_PACKAGECODEW )) { if (lstrlenW(val) != SQUISH_GUID_SIZE - 1) badconfig = TRUE; @@ -1324,23 +1325,23 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, goto done; } - if (!lstrcmpW(szProperty, INSTALLPROPERTY_HELPLINKW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_HELPTELEPHONEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLLOCATIONW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLSOURCEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_PUBLISHERW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_URLINFOABOUTW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_URLUPDATEINFOW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMINORW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMAJORW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTIDW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_REGCOMPANYW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_REGOWNERW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_INSTANCETYPEW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_HELPLINKW ) || + !strcmpW( szProperty, INSTALLPROPERTY_HELPTELEPHONEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_INSTALLDATEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_INSTALLLOCATIONW ) || + !strcmpW( szProperty, INSTALLPROPERTY_INSTALLSOURCEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_PUBLISHERW ) || + !strcmpW( szProperty, INSTALLPROPERTY_URLINFOABOUTW ) || + !strcmpW( szProperty, INSTALLPROPERTY_URLUPDATEINFOW ) || + !strcmpW( szProperty, INSTALLPROPERTY_VERSIONMINORW ) || + !strcmpW( szProperty, INSTALLPROPERTY_VERSIONMAJORW ) || + !strcmpW( szProperty, INSTALLPROPERTY_VERSIONSTRINGW ) || + !strcmpW( szProperty, INSTALLPROPERTY_PRODUCTIDW ) || + !strcmpW( szProperty, INSTALLPROPERTY_REGCOMPANYW ) || + !strcmpW( szProperty, INSTALLPROPERTY_REGOWNERW ) || + !strcmpW( szProperty, INSTALLPROPERTY_INSTANCETYPEW )) { val = msi_reg_get_value(props, package, &type); if (!val) @@ -1353,9 +1354,9 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, msi_free(val); - if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW )) szProperty = displayname; - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_VERSIONSTRINGW )) szProperty = displayversion; val = msi_reg_get_value(props, szProperty, &type); @@ -1364,14 +1365,14 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, r = msi_copy_outval(val, szValue, pcchValue); } - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_TRANSFORMSW ) || + !strcmpW( szProperty, INSTALLPROPERTY_LANGUAGEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_PRODUCTNAMEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_PACKAGECODEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_VERSIONW ) || + !strcmpW( szProperty, INSTALLPROPERTY_PRODUCTICONW ) || + !strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW )) { if (!prod && !classes) goto done; @@ -1389,7 +1390,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, r = msi_copy_outval(val, szValue, pcchValue); } - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_PRODUCTSTATEW )) { if (dwContext == MSIINSTALLCONTEXT_MACHINE) { @@ -1423,7 +1424,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, r = msi_copy_outval(val, szValue, pcchValue); } - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW )) { if (!prod && !classes) goto done; @@ -1554,7 +1555,7 @@ UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode, if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid) return ERROR_INVALID_PARAMETER; - if (!lstrcmpW(szUserSid, szLocalSid)) + if (szUserSid && !strcmpW( szUserSid, szLocalSid )) return ERROR_INVALID_PARAMETER; if (MSIREG_OpenUserDataProductKey(szProductCode, dwContext, NULL, @@ -1575,7 +1576,7 @@ UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode, if (res != ERROR_SUCCESS) goto done; - if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_TRANSFORMSW )) { if (MSIREG_OpenProductKey(szProductCode, NULL, dwContext, &prod, FALSE) != ERROR_SUCCESS) @@ -1594,25 +1595,25 @@ UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode, &udpatch, FALSE) != ERROR_SUCCESS) goto done; - if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW )) { if (dwContext == MSIINSTALLCONTEXT_USERMANAGED) szProperty = szManagedPackage; datakey = udpatch; } - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_INSTALLDATEW )) { datakey = patch; szProperty = szInstalled; } - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW )) { datakey = udpatch; } - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_UNINSTALLABLEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_PATCHSTATEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_DISPLAYNAMEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_MOREINFOURLW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_UNINSTALLABLEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_PATCHSTATEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_DISPLAYNAMEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_MOREINFOURLW )) { datakey = patch; } @@ -1766,24 +1767,26 @@ UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes) UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes) { - HANDLE file = INVALID_HANDLE_VALUE; - TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes); + msi_free(gszLogFile); + gszLogFile = NULL; if (szLogFile) { - lstrcpyW(gszLogFile,szLogFile); + HANDLE file; + if (!(attributes & INSTALLLOGATTRIBUTES_APPEND)) DeleteFileW(szLogFile); - file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); + file = CreateFileW(szLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); if (file != INVALID_HANDLE_VALUE) + { + gszLogFile = strdupW(szLogFile); CloseHandle(file); + } else - ERR("Unable to enable log %s\n",debugstr_w(szLogFile)); + ERR("Unable to enable log %s (%u)\n", debugstr_w(szLogFile), GetLastError()); } - else - gszLogFile[0] = '\0'; return ERROR_SUCCESS; } @@ -1944,6 +1947,7 @@ UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode, *pdwState = INSTALLSTATE_LOCAL; } + TRACE("-> %d\n", *pdwState); return ERROR_SUCCESS; } @@ -1982,6 +1986,11 @@ INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct) if (lstrlenW(szProduct) != GUID_SIZE - 1) return INSTALLSTATE_INVALIDARG; + if (szProduct[0] != '{' || szProduct[37] != '}') + return INSTALLSTATE_UNKNOWN; + + SetLastError( ERROR_SUCCESS ); + if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED, &prodkey, FALSE) != ERROR_SUCCESS && MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, @@ -2015,6 +2024,7 @@ done: RegCloseKey(prodkey); RegCloseKey(userdata); + TRACE("-> %d\n", state); return state; } @@ -2631,6 +2641,8 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) if (!squash_guid( szProduct, squishProduct )) return INSTALLSTATE_INVALIDARG; + SetLastError( ERROR_SUCCESS ); + if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED, &hkey, FALSE) != ERROR_SUCCESS && MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED, @@ -2711,17 +2723,17 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) msi_free(path); } - - TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r); msi_free(components); if (missing) - return INSTALLSTATE_ADVERTISED; + r = INSTALLSTATE_ADVERTISED; + else if (source) + r = INSTALLSTATE_SOURCE; + else + r = INSTALLSTATE_LOCAL; - if (source) - return INSTALLSTATE_SOURCE; - - return INSTALLSTATE_LOCAL; + TRACE("-> %d\n", r); + return r; } /****************************************************************** @@ -3543,8 +3555,8 @@ UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature, LPWSTR ptr; DWORD sz; - FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), - dwReinstallMode); + FIXME("%s %s 0x%08x\n", + debugstr_w(szProduct), debugstr_w(szFeature), dwReinstallMode); ptr = reinstallmode; @@ -3661,8 +3673,10 @@ UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions, handle = CreateFileW( szFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL ); if (handle == INVALID_HANDLE_VALUE) + { + WARN("can't open file %u\n", GetLastError()); return ERROR_FILE_NOT_FOUND; - + } length = GetFileSize( handle, NULL ); mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL ); @@ -3771,6 +3785,31 @@ UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD handler, return ERROR_SUCCESS; } +/*********************************************************************** + * MsiInstallMissingComponentA [MSI.@] + */ +UINT WINAPI MsiInstallMissingComponentA( LPCSTR product, LPCSTR component, INSTALLSTATE state ) +{ + UINT r; + WCHAR *productW = NULL, *componentW = NULL; + + TRACE("%s, %s, %d\n", debugstr_a(product), debugstr_a(component), state); + + if (product && !(productW = strdupAtoW( product ))) + return ERROR_OUTOFMEMORY; + + if (component && !(componentW = strdupAtoW( component ))) + { + msi_free( productW ); + return ERROR_OUTOFMEMORY; + } + + r = MsiInstallMissingComponentW( productW, componentW, state ); + msi_free( productW ); + msi_free( componentW ); + return r; +} + /*********************************************************************** * MsiInstallMissingComponentW [MSI.@] */ diff --git a/reactos/dll/win32/msi/msi.rbuild b/reactos/dll/win32/msi/msi.rbuild index 8c98a6d5c46..4dd17cc0655 100644 --- a/reactos/dll/win32/msi/msi.rbuild +++ b/reactos/dll/win32/msi/msi.rbuild @@ -11,6 +11,7 @@ action.c alter.c appsearch.c + assembly.c automation.c classes.c cond.tab.c diff --git a/reactos/dll/win32/msi/msi.rc b/reactos/dll/win32/msi/msi.rc index d81484f66bb..c980fa891d2 100644 --- a/reactos/dll/win32/msi/msi.rc +++ b/reactos/dll/win32/msi/msi.rc @@ -19,45 +19,56 @@ */ #include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "winnls.h" -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT -#include "version.rc" - -#include "msi_Bg.rc" -#include "msi_Da.rc" -#include "msi_En.rc" -#include "msi_Es.rc" -#include "msi_Fi.rc" -#include "msi_Hu.rc" -#include "msi_Ko.rc" -#include "msi_Nl.rc" -#include "msi_No.rc" -#include "msi_Pl.rc" -#include "msi_Sv.rc" -#include "msi_Tr.rc" -#include "msi_Uk.rc" -#include "msi_Zh.rc" - -/* UTF-8 */ -#include "msi_De.rc" -#include "msi_Fr.rc" -#include "msi_It.rc" -#include "msi_Lt.rc" -#include "msi_Pt.rc" -#include "msi_Ro.rc" -#include "msi_Ru.rc" -#include "msi_Si.rc" -#include "msi_Sr.rc" +STRINGTABLE +{ + 4 "The specified installation package could not be opened. Please check the file path and try again." + 5 "path %s not found" + 9 "insert disk %s" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parameter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|product_code} [property]\n" \ + "\t/package {package|product_code} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|product_code}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|product_code} [property]\n" \ + "\t/x {package|product_code} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patch_package [property]\n" \ + "\t/p patch_package /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" + 11 "enter which folder contains %s" + 12 "install source for feature missing" + 13 "network drive for feature missing" + 14 "feature from:" + 15 "choose which folder contains %s" +} LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* @makedep: msiserver.tlb */ 1 TYPELIB msiserver.tlb +/* @makedep: msiserver.rgs */ +1 WINE_REGISTRY msiserver.rgs + /* @makedep: instadvert.bmp */ 0x1001 BITMAP instadvert.bmp @@ -66,3 +77,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* @makedep: instlocal.bmp */ 0x1003 BITMAP instlocal.bmp + +#define WINE_FILEDESCRIPTION_STR "Wine MSI dll" +#define WINE_FILENAME_STR "msi.dll" +#define WINE_FILEVERSION 4,5,6001,22159 +#define WINE_FILEVERSION_STR "4.5.6001.22159" +#define WINE_PRODUCTVERSION 4,5,6001,22159 +#define WINE_PRODUCTVERSION_STR "4.5.6001.22159" + +#include "wine/wine_common_ver.rc" diff --git a/reactos/dll/win32/msi/msi.spec b/reactos/dll/win32/msi/msi.spec index fd047f8a652..c1e35530782 100644 --- a/reactos/dll/win32/msi/msi.spec +++ b/reactos/dll/win32/msi/msi.spec @@ -76,7 +76,7 @@ 80 stdcall MsiGetTargetPathW(long wstr ptr ptr) 81 stdcall MsiGetUserInfoA(str ptr ptr ptr ptr ptr ptr) 82 stdcall MsiGetUserInfoW(wstr ptr ptr ptr ptr ptr ptr) -83 stub MsiInstallMissingComponentA +83 stdcall MsiInstallMissingComponentA(str str long) 84 stdcall MsiInstallMissingComponentW(wstr wstr long) 85 stub MsiInstallMissingFileA 86 stub MsiInstallMissingFileW diff --git a/reactos/dll/win32/msi/msi_main.c b/reactos/dll/win32/msi/msi_main.c index df29184ab92..93f65430545 100644 --- a/reactos/dll/win32/msi/msi_main.c +++ b/reactos/dll/win32/msi/msi_main.c @@ -28,7 +28,9 @@ #include "winreg.h" #include "shlwapi.h" #include "oleauto.h" +#include "rpcproxy.h" #include "msipriv.h" +#include "msiserver.h" #include "wine/debug.h" @@ -44,7 +46,7 @@ INSTALLUI_HANDLERW gUIHandlerW = NULL; INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL; DWORD gUIFilter = 0; LPVOID gUIContext = NULL; -WCHAR gszLogFile[MAX_PATH]; +WCHAR *gszLogFile = NULL; HINSTANCE msi_hInstance; static WCHAR msi_path[MAX_PATH]; @@ -78,6 +80,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) if (msi_typelib) ITypeLib_Release( msi_typelib ); msi_dialog_unregister_class(); msi_free_handle_table(); + msi_free( gszLogFile ); break; } return TRUE; @@ -117,14 +120,19 @@ ITypeLib *get_msi_typelib( LPWSTR *path ) } typedef struct tagIClassFactoryImpl { - const IClassFactoryVtbl *lpVtbl; + IClassFactory IClassFactory_iface; HRESULT (*create_object)( IUnknown*, LPVOID* ); } IClassFactoryImpl; +static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); +} + static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid,LPVOID *ppobj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); TRACE("%p %s %p\n",This,debugstr_guid(riid),ppobj); @@ -153,7 +161,7 @@ static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface) static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); IUnknown *unk = NULL; HRESULT r; @@ -189,9 +197,9 @@ static const IClassFactoryVtbl MsiCF_Vtbl = MsiCF_LockServer }; -static IClassFactoryImpl MsiServer_CF = { &MsiCF_Vtbl, create_msiserver }; -static IClassFactoryImpl WineMsiCustomRemote_CF = { &MsiCF_Vtbl, create_msi_custom_remote }; -static IClassFactoryImpl WineMsiRemotePackage_CF = { &MsiCF_Vtbl, create_msi_remote_package }; +static IClassFactoryImpl MsiServer_CF = { { &MsiCF_Vtbl }, create_msiserver }; +static IClassFactoryImpl WineMsiCustomRemote_CF = { { &MsiCF_Vtbl }, create_msi_custom_remote }; +static IClassFactoryImpl WineMsiRemotePackage_CF = { { &MsiCF_Vtbl }, create_msi_remote_package }; /****************************************************************** * DllGetClassObject [MSI.@] @@ -200,28 +208,28 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - if ( IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ) + if ( IsEqualCLSID (rclsid, &CLSID_MsiInstaller) ) { *ppv = &MsiServer_CF; return S_OK; } - if ( IsEqualCLSID (rclsid, &CLSID_IWineMsiRemoteCustomAction) ) + if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemoteCustomAction) ) { *ppv = &WineMsiCustomRemote_CF; return S_OK; } - if ( IsEqualCLSID (rclsid, &CLSID_IWineMsiRemotePackage) ) + if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemotePackage) ) { *ppv = &WineMsiRemotePackage_CF; return S_OK; } - if( IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) || - IsEqualCLSID (rclsid, &CLSID_IMsiServer) || - IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) || - IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) ) + if( IsEqualCLSID (rclsid, &CLSID_MsiServerMessage) || + IsEqualCLSID (rclsid, &CLSID_MsiServer) || + IsEqualCLSID (rclsid, &CLSID_PSFactoryBuffer) || + IsEqualCLSID (rclsid, &CLSID_MsiServerX3) ) { FIXME("create %s object\n", debugstr_guid( rclsid )); } diff --git a/reactos/dll/win32/msi/msipriv.h b/reactos/dll/win32/msi/msipriv.h index 0361ff42c6e..56a8a93c807 100644 --- a/reactos/dll/win32/msi/msipriv.h +++ b/reactos/dll/win32/msi/msipriv.h @@ -32,6 +32,7 @@ #include "msidefs.h" #include "objbase.h" #include "objidl.h" +#include "fusion.h" #include "winnls.h" #include "winver.h" #include "wine/list.h" @@ -162,6 +163,14 @@ typedef struct tagMSIPATCHINFO MSIPATCHSTATE state; } MSIPATCHINFO; +typedef struct tagMSIBINARY +{ + struct list entry; + WCHAR *source; + WCHAR *tmpfile; + HMODULE module; +} MSIBINARY; + typedef struct _column_info { LPCWSTR table; @@ -315,6 +324,13 @@ enum platform PLATFORM_X64 }; +enum clr_version +{ + CLR_VERSION_V11, + CLR_VERSION_V20, + CLR_VERSION_MAX +}; + typedef struct tagMSIPACKAGE { MSIOBJECTHDR hdr; @@ -329,8 +345,12 @@ typedef struct tagMSIPACKAGE struct list files; struct list tempfiles; struct list folders; + struct list binaries; LPWSTR ActionFormat; LPWSTR LastAction; + HANDLE log_file; + IAssemblyCache *cache_net[CLR_VERSION_MAX]; + IAssemblyCache *cache_sxs; struct list classes; struct list extensions; @@ -401,6 +421,18 @@ typedef struct tagMSIFEATURE struct list Components; } MSIFEATURE; +typedef struct tagMSIASSEMBLY +{ + LPWSTR feature; + LPWSTR manifest; + LPWSTR application; + DWORD attributes; + LPWSTR display_name; + LPWSTR tempdir; + BOOL installed; + BOOL clr_version[CLR_VERSION_MAX]; +} MSIASSEMBLY; + typedef struct tagMSICOMPONENT { struct list entry; @@ -419,6 +451,7 @@ typedef struct tagMSICOMPONENT INT RefCount; LPWSTR FullKeypath; LPWSTR AdvertiseString; + MSIASSEMBLY *assembly; unsigned int anyAbsent:1; unsigned int hasAdvertiseFeature:1; @@ -466,6 +499,7 @@ typedef enum _msi_file_state { msifs_present, msifs_installed, msifs_skipped, + msifs_hashmatch } msi_file_state; typedef struct tagMSIFILE @@ -625,14 +659,6 @@ DEFINE_GUID(CLSID_IMsiServerX2, 0x000C1090,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x0 DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); - -DEFINE_GUID(CLSID_IWineMsiRemoteCustomAction,0xBA26E6FA,0x4F27,0x4f56,0x95,0x3A,0x3F,0x90,0x27,0x20,0x18,0xAA); -DEFINE_GUID(CLSID_IWineMsiRemotePackage,0x902b3592,0x9d08,0x4dfd,0xa5,0x93,0xd0,0x7c,0x52,0x54,0x64,0x21); - -DEFINE_GUID(CLSID_MsiTransform, 0x000c1082,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); -DEFINE_GUID(CLSID_MsiDatabase, 0x000c1084,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); -DEFINE_GUID(CLSID_MsiPatch, 0x000c1086,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); - /* handle unicode/ascii output in the Msi* API functions */ typedef struct { BOOL unicode; @@ -688,6 +714,8 @@ extern const WCHAR *msi_string_lookup_id( const string_table *st, UINT id ); extern HRESULT msi_init_string_table( IStorage *stg ); extern string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref ); extern UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *bytes_per_strref ); +extern UINT msi_get_string_table_codepage( const string_table *st ); +extern UINT msi_set_string_table_codepage( string_table *st, UINT codepage ); extern BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ); extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table ); @@ -823,6 +851,7 @@ extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid); extern UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode); +extern UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode); extern UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create); extern UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode); extern UINT MSIREG_DeleteLocalClassesFeaturesKey(LPCWSTR szProductCode); @@ -834,7 +863,9 @@ extern DWORD msi_version_str_to_dword(LPCWSTR p); extern void msi_parse_version_string(LPCWSTR, PDWORD, PDWORD); extern VS_FIXEDFILEINFO *msi_get_disk_file_version(LPCWSTR); extern int msi_compare_file_versions(VS_FIXEDFILEINFO *, const WCHAR *); - +extern int msi_compare_font_versions(const WCHAR *, const WCHAR *); +extern DWORD msi_get_disk_file_size(LPCWSTR); +extern BOOL msi_file_hash_matches(MSIFILE *); extern LONG msi_reg_set_val_str( HKEY hkey, LPCWSTR name, LPCWSTR value ); extern LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value ); @@ -879,7 +910,7 @@ extern INSTALLUI_HANDLERW gUIHandlerW; extern INSTALLUI_HANDLER_RECORD gUIHandlerRecord; extern DWORD gUIFilter; extern LPVOID gUIContext; -extern WCHAR gszLogFile[MAX_PATH]; +extern WCHAR *gszLogFile; extern HINSTANCE msi_hInstance; /* action related functions */ @@ -888,102 +919,6 @@ extern UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action, UIN extern void ACTION_FinishCustomActions( const MSIPACKAGE* package); extern UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action, UINT script, BOOL execute); -static inline void msi_feature_set_state(MSIPACKAGE *package, - MSIFEATURE *feature, - INSTALLSTATE state) -{ - if (!package->ProductCode) - { - feature->ActionRequest = state; - feature->Action = state; - } - else if (state == INSTALLSTATE_ABSENT) - { - switch (feature->Installed) - { - case INSTALLSTATE_ABSENT: - feature->ActionRequest = INSTALLSTATE_UNKNOWN; - feature->Action = INSTALLSTATE_UNKNOWN; - break; - default: - feature->ActionRequest = state; - feature->Action = state; - } - } - else if (state == INSTALLSTATE_SOURCE) - { - switch (feature->Installed) - { - case INSTALLSTATE_ABSENT: - case INSTALLSTATE_SOURCE: - feature->ActionRequest = state; - feature->Action = state; - break; - case INSTALLSTATE_LOCAL: - feature->ActionRequest = INSTALLSTATE_LOCAL; - feature->Action = INSTALLSTATE_LOCAL; - break; - default: - feature->ActionRequest = INSTALLSTATE_UNKNOWN; - feature->Action = INSTALLSTATE_UNKNOWN; - } - } - else - { - feature->ActionRequest = state; - feature->Action = state; - } - if (feature->Attributes & msidbFeatureAttributesUIDisallowAbsent) - { - feature->Action = INSTALLSTATE_UNKNOWN; - } -} - -static inline void msi_component_set_state(MSIPACKAGE *package, - MSICOMPONENT *comp, - INSTALLSTATE state) -{ - if (!package->ProductCode) - { - comp->ActionRequest = state; - comp->Action = state; - } - else if (state == INSTALLSTATE_ABSENT) - { - switch (comp->Installed) - { - case INSTALLSTATE_LOCAL: - case INSTALLSTATE_SOURCE: - case INSTALLSTATE_DEFAULT: - comp->ActionRequest = state; - comp->Action = state; - break; - default: - comp->ActionRequest = INSTALLSTATE_UNKNOWN; - comp->Action = INSTALLSTATE_UNKNOWN; - } - } - else if (state == INSTALLSTATE_SOURCE) - { - if (comp->Installed == INSTALLSTATE_ABSENT || - (comp->Installed == INSTALLSTATE_SOURCE && comp->hasLocalFeature)) - { - comp->ActionRequest = state; - comp->Action = state; - } - else - { - comp->ActionRequest = INSTALLSTATE_UNKNOWN; - comp->Action = INSTALLSTATE_UNKNOWN; - } - } - else - { - comp->ActionRequest = state; - comp->Action = state; - } -} - /* actions in other modules */ extern UINT ACTION_AppSearch(MSIPACKAGE *package); extern UINT ACTION_CCPSearch(MSIPACKAGE *package); @@ -1003,6 +938,8 @@ extern UINT ACTION_UnregisterExtensionInfo(MSIPACKAGE *package); extern UINT ACTION_UnregisterFonts(MSIPACKAGE *package); extern UINT ACTION_UnregisterMIMEInfo(MSIPACKAGE *package); extern UINT ACTION_UnregisterProgIdInfo(MSIPACKAGE *package); +extern UINT ACTION_MsiPublishAssemblies(MSIPACKAGE *package); +extern UINT ACTION_MsiUnpublishAssemblies(MSIPACKAGE *package); /* Helpers */ extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data ); @@ -1011,8 +948,8 @@ extern LPWSTR msi_dup_property( MSIDATABASE *db, LPCWSTR prop ); extern UINT msi_set_property( MSIDATABASE *, LPCWSTR, LPCWSTR ); extern UINT msi_get_property( MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD ); extern int msi_get_property_int( MSIDATABASE *package, LPCWSTR prop, int def ); -extern LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, - BOOL set_prop, BOOL load_prop, MSIFOLDER **folder); +extern LPWSTR resolve_source_folder(MSIPACKAGE *package, LPCWSTR name, MSIFOLDER **folder); +extern LPWSTR resolve_target_folder(MSIPACKAGE *package, LPCWSTR name, BOOL set_prop, BOOL load_prop, MSIFOLDER **folder); extern LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file); extern void msi_reset_folders( MSIPACKAGE *package, BOOL source ); extern MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component ); @@ -1027,7 +964,7 @@ extern LPWSTR build_directory_name(DWORD , ...); extern BOOL create_full_pathW(const WCHAR *path); extern void reduce_to_longfilename(WCHAR*); extern LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR); -extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature); +extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, MSIFEATURE *feature); extern UINT register_unique_action(MSIPACKAGE *, LPCWSTR); extern BOOL check_unique_action(const MSIPACKAGE *, LPCWSTR); extern WCHAR* generate_error_string(MSIPACKAGE *, UINT, DWORD, ... ); @@ -1035,6 +972,10 @@ extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid, MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value); extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix); extern UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace); +extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *); +extern UINT install_assembly(MSIPACKAGE *, MSICOMPONENT *); +extern WCHAR *font_version_from_file(const WCHAR *); +extern WCHAR **msi_split_string(const WCHAR *, WCHAR); /* media */ @@ -1053,6 +994,7 @@ typedef struct } MSICABDATA; extern UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi); +extern UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi); extern void msi_free_media_info(MSIMEDIAINFO *mi); extern BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data); @@ -1149,8 +1091,12 @@ static const WCHAR szAdminUser[] = {'A','d','m','i','n','U','s','e','r',0}; static const WCHAR szIntel[] = {'I','n','t','e','l',0}; static const WCHAR szIntel64[] = {'I','n','t','e','l','6','4',0}; static const WCHAR szX64[] = {'x','6','4',0}; +static const WCHAR szAMD64[] = {'A','M','D','6','4',0}; static const WCHAR szWow6432NodeCLSID[] = {'W','o','w','6','4','3','2','N','o','d','e','\\','C','L','S','I','D',0}; static const WCHAR szWow6432Node[] = {'W','o','w','6','4','3','2','N','o','d','e',0}; +static const WCHAR szStreams[] = {'_','S','t','r','e','a','m','s',0}; +static const WCHAR szStorages[] = {'_','S','t','o','r','a','g','e','s',0}; +static const WCHAR szMsiPublishAssemblies[] = {'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0}; /* memory allocation macro functions */ static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1); diff --git a/reactos/dll/win32/msi/msiquery.c b/reactos/dll/win32/msi/msiquery.c index cf6959391d3..4ccf5f65f8f 100644 --- a/reactos/dll/win32/msi/msiquery.c +++ b/reactos/dll/win32/msi/msiquery.c @@ -75,9 +75,9 @@ UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, LPCWSTR table_name, UINT *n NULL, &haystack_table_name ); if( r != ERROR_SUCCESS ) return r; - x = lstrcmpW( name, col_name ); + x = strcmpW( name, col_name ); if( table_name ) - x |= lstrcmpW( table_name, haystack_table_name ); + x |= strcmpW( table_name, haystack_table_name ); msi_free( col_name ); msi_free( haystack_table_name ); if( !x ) diff --git a/reactos/dll/win32/msi/msiserver.idl b/reactos/dll/win32/msi/msiserver.idl index e74c22c0b19..58c5b3cf99f 100644 --- a/reactos/dll/win32/msi/msiserver.idl +++ b/reactos/dll/win32/msi/msiserver.idl @@ -86,6 +86,99 @@ interface IWineMsiRemoteCustomAction : IUnknown [out] BSTR *function, [out] IWineMsiRemotePackage **package ); } +[ + uuid(000c101c-0000-0000-c000-000000000046), + oleautomation, + object +] +interface IMsiServer : IUnknown +{ + /* FIXME: methods */ +} + +[ + uuid(000c101d-0000-0000-c000-000000000046), + oleautomation, + object +] +interface IMsiMessage : IUnknown +{ + /* FIXME: methods */ +} + +[ + uuid(000c1025-0000-0000-c000-000000000046), + oleautomation, + object +] +interface IMsiCustomAction : IUnknown +{ + /* FIXME: methods */ +} + +[ + uuid(000c1033-0000-0000-c000-000000000046), + oleautomation, + object +] +interface IMsiRemoteAPI : IUnknown +{ + /* FIXME: methods */ +} + +[ + helpstring("Msi install server"), + progid("IMsiServer"), + uuid(000c101c-0000-0000-c000-000000000046) +] +coclass MsiServer { interface IMsiServer; } + +[ + helpstring("Microsoft Windows Installer Message RPC"), + progid("WindowsInstaller.Message"), + uuid(000c101d-0000-0000-c000-000000000046) +] +coclass MsiServerMessage { interface IMsiMessage; } + +[ + threading(both), + uuid(000c103e-0000-0000-c000-000000000046) +] +coclass PSFactoryBuffer { interface IPSFactoryBuffer; } + +[ + uuid(000c1082-0000-0000-c000-000000000046) +] +coclass MsiTransform { } + +[ + uuid(000c1084-0000-0000-c000-000000000046) +] +coclass MsiDatabase { } + +[ + uuid(000c1086-0000-0000-c000-000000000046) +] +coclass MsiPatch { } + +[ + threading(apartment), + uuid(000c1094-0000-0000-c000-000000000046) +] +/* FIXME: unidentified class */ +coclass MsiServerX3 { interface IMsiServer; } + +[ + uuid(ba26e6fa-4f27-4f56-953a-3f90272018aa) +] +coclass WineMsiRemoteCustomAction { interface WineMsiRemoteCustomAction; } + +[ + uuid(902b3592-9d08-4dfd-a593-d07c52546421) +] +coclass WineMsiRemotePackage { interface WineMsiRemotePackage; } + + [ uuid(000C1092-0000-0000-C000-000000000046), version(1.0) ] library WindowsInstaller { @@ -452,4 +545,12 @@ library WindowsInstaller properties: methods: } + + [ + helpstring("Microsoft Windows Installer"), + threading(apartment), + progid("WindowsInstaller.Installer"), + uuid(000c1090-0000-0000-c000-000000000046) + ] + coclass MsiInstaller { interface Installer; } } diff --git a/reactos/dll/win32/msi/package.c b/reactos/dll/win32/msi/package.c index 32576a0362c..c84c28a7516 100644 --- a/reactos/dll/win32/msi/package.c +++ b/reactos/dll/win32/msi/package.c @@ -59,8 +59,7 @@ static void remove_tracked_tempfiles( MSIPACKAGE *package ) list_remove( &temp->entry ); TRACE("deleting temp file %s\n", debugstr_w( temp->Path )); - if (!DeleteFileW( temp->Path )) - ERR("failed to delete %s\n", debugstr_w( temp->Path )); + DeleteFileW( temp->Path ); msi_free( temp->Path ); msi_free( temp ); } @@ -111,6 +110,17 @@ static void free_extension( MSIEXTENSION *ext ) msi_free( ext ); } +static void free_assembly( MSIASSEMBLY *assembly ) +{ + msi_free( assembly->feature ); + msi_free( assembly->manifest ); + msi_free( assembly->application ); + msi_free( assembly->display_name ); + if (assembly->tempdir) RemoveDirectoryW( assembly->tempdir ); + msi_free( assembly->tempdir ); + msi_free( assembly ); +} + static void free_package_structures( MSIPACKAGE *package ) { INT i; @@ -154,6 +164,7 @@ static void free_package_structures( MSIPACKAGE *package ) msi_free( comp->Condition ); msi_free( comp->KeyPath ); msi_free( comp->FullKeypath ); + if (comp->assembly) free_assembly( comp->assembly ); msi_free( comp ); } @@ -275,6 +286,20 @@ static void free_package_structures( MSIPACKAGE *package ) msi_free( patch ); } + LIST_FOR_EACH_SAFE( item, cursor, &package->binaries ) + { + MSIBINARY *binary = LIST_ENTRY( item, MSIBINARY, entry ); + + list_remove( &binary->entry ); + if (binary->module) + FreeLibrary( binary->module ); + if (!DeleteFileW( binary->tmpfile )) + ERR("failed to delete %s (%u)\n", debugstr_w(binary->tmpfile), GetLastError()); + msi_free( binary->source ); + msi_free( binary->tmpfile ); + msi_free( binary ); + } + msi_free( package->BaseURL ); msi_free( package->PackagePath ); msi_free( package->ProductCode ); @@ -288,13 +313,19 @@ static void free_package_structures( MSIPACKAGE *package ) static void MSI_FreePackage( MSIOBJECTHDR *arg) { - MSIPACKAGE *package= (MSIPACKAGE*) arg; + UINT i; + MSIPACKAGE *package = (MSIPACKAGE *)arg; if( package->dialog ) msi_dialog_destroy( package->dialog ); msiobj_release( &package->db->hdr ); free_package_structures(package); + CloseHandle( package->log_file ); + + for (i = 0; i < CLR_VERSION_MAX; i++) + if (package->cache_net[i]) IAssemblyCache_Release( package->cache_net[i] ); + if (package->cache_sxs) IAssemblyCache_Release( package->cache_sxs ); } static UINT create_temp_property_table(MSIPACKAGE *package) @@ -511,7 +542,7 @@ static LPWSTR get_fusion_filename(MSIPACKAGE *package) index++; /* verify existence of fusion.dll .Net 3.0 does not install a new one */ - if (lstrcmpW(ver, name) < 0) + if (strcmpW( ver, name ) < 0) { LPWSTR check; size = lstrlenW(windir) + lstrlenW(subdir) + lstrlenW(name) +lstrlenW(fusion) + 3; @@ -1046,6 +1077,7 @@ static MSIPACKAGE *msi_alloc_package( void ) list_init( &package->sourcelist_info ); list_init( &package->sourcelist_media ); list_init( &package->patches ); + list_init( &package->binaries ); } return package; @@ -1121,6 +1153,8 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) if (package->WordCount & msidbSumInfoSourceTypeAdminImage) msi_load_admin_properties( package ); + + package->log_file = INVALID_HANDLE_VALUE; } return package; @@ -1313,7 +1347,7 @@ static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package ) package->platform = PLATFORM_INTEL; else if (!strcmpW( template, szIntel64 )) package->platform = PLATFORM_INTEL64; - else if (!strcmpW( template, szX64 )) + else if (!strcmpW( template, szX64 ) || !strcmpW( template, szAMD64 )) package->platform = PLATFORM_X64; else { @@ -1321,9 +1355,14 @@ static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package ) msi_free( template ); return ERROR_INSTALL_PLATFORM_UNSUPPORTED; } - + p++; + if (!*p) + { + msi_free( template ); + return ERROR_SUCCESS; + } count = 1; - for (q = ++p; (q = strchrW( q, ',' )); q++) count++; + for (q = p; (q = strchrW( q, ',' )); q++) count++; package->langids = msi_alloc( count * sizeof(LANGID) ); if (!package->langids) @@ -1367,7 +1406,17 @@ static UINT validate_package( MSIPACKAGE *package ) } for (i = 0; i < package->num_langids; i++) { - if (!package->langids[i] || IsValidLocale( package->langids[i], LCID_INSTALLED )) + LANGID langid = package->langids[i]; + + if (PRIMARYLANGID( langid ) == LANG_NEUTRAL) + { + langid = MAKELANGID( PRIMARYLANGID( GetSystemDefaultLangID() ), SUBLANGID( langid ) ); + } + if (SUBLANGID( langid ) == SUBLANG_NEUTRAL) + { + langid = MAKELANGID( PRIMARYLANGID( langid ), SUBLANGID( GetSystemDefaultLangID() ) ); + } + if (IsValidLocale( langid, LCID_INSTALLED )) return ERROR_SUCCESS; } return ERROR_INSTALL_LANGUAGE_UNSUPPORTED; @@ -1551,6 +1600,10 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) msi_adjust_privilege_properties( package ); } + if (gszLogFile) + package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + *pPackage = package; return ERROR_SUCCESS; } @@ -1657,17 +1710,13 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, {'S','e','t','P','r','o','g','r','e','s','s',0}; static const WCHAR szActionText[] = {'A','c','t','i','o','n','T','e','x','t',0}; - DWORD log_type = 0; LPWSTR message; - DWORD sz; - DWORD total_size = 0; - INT i; - INT rc; + DWORD sz, total_size = 0, log_type = 0; + INT i, rc = 0; char *msg; int len; TRACE("%x\n", eMessageType); - rc = 0; if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ERROR) log_type |= INSTALLLOGMODE_ERROR; @@ -1773,20 +1822,12 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MsiCloseHandle( rec ); } - if ((!rc) && (gszLogFile[0]) && !((eMessageType & 0xff000000) == - INSTALLMESSAGE_PROGRESS)) + if (!rc && package->log_file != INVALID_HANDLE_VALUE && + (eMessageType & 0xff000000) != INSTALLMESSAGE_PROGRESS) { - DWORD write; - HANDLE log_file = CreateFileW(gszLogFile,GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (log_file != INVALID_HANDLE_VALUE) - { - SetFilePointer(log_file,0, NULL, FILE_END); - WriteFile(log_file,msg,strlen(msg),&write,NULL); - WriteFile(log_file,"\n",1,&write,NULL); - CloseHandle(log_file); - } + DWORD written; + WriteFile( package->log_file, msg, len - 1, &written, NULL ); + WriteFile( package->log_file, "\n", 1, &written, NULL ); } msi_free( msg ); msi_free( message ); @@ -2248,14 +2289,14 @@ UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, } typedef struct _msi_remote_package_impl { - const IWineMsiRemotePackageVtbl *lpVtbl; + IWineMsiRemotePackage IWineMsiRemotePackage_iface; MSIHANDLE package; LONG refs; } msi_remote_package_impl; -static inline msi_remote_package_impl* mrp_from_IWineMsiRemotePackage( IWineMsiRemotePackage* iface ) +static inline msi_remote_package_impl *impl_from_IWineMsiRemotePackage( IWineMsiRemotePackage *iface ) { - return (msi_remote_package_impl*) iface; + return CONTAINING_RECORD(iface, msi_remote_package_impl, IWineMsiRemotePackage_iface); } static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface, @@ -2274,14 +2315,14 @@ static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface, static ULONG WINAPI mrp_AddRef( IWineMsiRemotePackage *iface ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); return InterlockedIncrement( &This->refs ); } static ULONG WINAPI mrp_Release( IWineMsiRemotePackage *iface ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); ULONG r; r = InterlockedDecrement( &This->refs ); @@ -2295,14 +2336,14 @@ static ULONG WINAPI mrp_Release( IWineMsiRemotePackage *iface ) static HRESULT WINAPI mrp_SetMsiHandle( IWineMsiRemotePackage *iface, MSIHANDLE handle ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); This->package = handle; return S_OK; } static HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHANDLE *handle ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); IWineMsiRemoteDatabase *rdb = NULL; HRESULT hr; MSIHANDLE hdb; @@ -2329,7 +2370,7 @@ static HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHA static HRESULT WINAPI mrp_GetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR *value, DWORD *size ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r; r = MsiGetPropertyW(This->package, (LPWSTR)property, (LPWSTR)value, size); @@ -2341,63 +2382,63 @@ static HRESULT WINAPI mrp_GetProperty( IWineMsiRemotePackage *iface, BSTR proper static HRESULT WINAPI mrp_SetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR value ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiSetPropertyW(This->package, property, value); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_ProcessMessage( IWineMsiRemotePackage *iface, INSTALLMESSAGE message, MSIHANDLE record ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiProcessMessage(This->package, message, record); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_DoAction( IWineMsiRemotePackage *iface, BSTR action ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiDoActionW(This->package, action); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_Sequence( IWineMsiRemotePackage *iface, BSTR table, int sequence ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiSequenceW(This->package, table, sequence); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_GetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR *value, DWORD *size ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiGetTargetPathW(This->package, (LPWSTR)folder, (LPWSTR)value, size); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_SetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiSetTargetPathW(This->package, folder, value); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_GetSourcePath( IWineMsiRemotePackage *iface, BSTR folder, BSTR *value, DWORD *size ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiGetSourcePathW(This->package, (LPWSTR)folder, (LPWSTR)value, size); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_GetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL *ret ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); *ret = MsiGetMode(This->package, mode); return S_OK; } static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL state ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiSetMode(This->package, mode, state); return HRESULT_FROM_WIN32(r); } @@ -2405,14 +2446,14 @@ static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature, INSTALLSTATE *installed, INSTALLSTATE *action ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiGetFeatureStateW(This->package, feature, installed, action); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_SetFeatureState( IWineMsiRemotePackage *iface, BSTR feature, INSTALLSTATE state ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiSetFeatureStateW(This->package, feature, state); return HRESULT_FROM_WIN32(r); } @@ -2420,28 +2461,28 @@ static HRESULT WINAPI mrp_SetFeatureState( IWineMsiRemotePackage *iface, BSTR fe static HRESULT WINAPI mrp_GetComponentState( IWineMsiRemotePackage *iface, BSTR component, INSTALLSTATE *installed, INSTALLSTATE *action ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiGetComponentStateW(This->package, component, installed, action); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_SetComponentState( IWineMsiRemotePackage *iface, BSTR component, INSTALLSTATE state ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiSetComponentStateW(This->package, component, state); return HRESULT_FROM_WIN32(r); } static HRESULT WINAPI mrp_GetLanguage( IWineMsiRemotePackage *iface, LANGID *language ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); *language = MsiGetLanguage(This->package); return S_OK; } static HRESULT WINAPI mrp_SetInstallLevel( IWineMsiRemotePackage *iface, int level ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiSetInstallLevel(This->package, level); return HRESULT_FROM_WIN32(r); } @@ -2450,7 +2491,7 @@ static HRESULT WINAPI mrp_FormatRecord( IWineMsiRemotePackage *iface, MSIHANDLE BSTR *value) { DWORD size = 0; - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiFormatRecordW(This->package, record, NULL, &size); if (r == ERROR_SUCCESS) { @@ -2465,7 +2506,7 @@ static HRESULT WINAPI mrp_FormatRecord( IWineMsiRemotePackage *iface, MSIHANDLE static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR condition ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiEvaluateConditionW(This->package, condition); return HRESULT_FROM_WIN32(r); } @@ -2473,7 +2514,7 @@ static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR static HRESULT WINAPI mrp_GetFeatureCost( IWineMsiRemotePackage *iface, BSTR feature, INT cost_tree, INSTALLSTATE state, INT *cost ) { - msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); UINT r = MsiGetFeatureCostW(This->package, feature, cost_tree, state, cost); return HRESULT_FROM_WIN32(r); } @@ -2514,7 +2555,7 @@ HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj ) if (!This) return E_OUTOFMEMORY; - This->lpVtbl = &msi_remote_package_vtbl; + This->IWineMsiRemotePackage_iface.lpVtbl = &msi_remote_package_vtbl; This->package = 0; This->refs = 1; @@ -2528,6 +2569,11 @@ UINT msi_package_add_info(MSIPACKAGE *package, DWORD context, DWORD options, { MSISOURCELISTINFO *info; + LIST_FOR_EACH_ENTRY( info, &package->sourcelist_info, MSISOURCELISTINFO, entry ) + { + if (!strcmpW( info->value, value )) return ERROR_SUCCESS; + } + info = msi_alloc(sizeof(MSISOURCELISTINFO)); if (!info) return ERROR_OUTOFMEMORY; @@ -2546,6 +2592,11 @@ UINT msi_package_add_media_disk(MSIPACKAGE *package, DWORD context, DWORD option { MSIMEDIADISK *disk; + LIST_FOR_EACH_ENTRY( disk, &package->sourcelist_media, MSIMEDIADISK, entry ) + { + if (disk->disk_id == disk_id) return ERROR_SUCCESS; + } + disk = msi_alloc(sizeof(MSIMEDIADISK)); if (!disk) return ERROR_OUTOFMEMORY; diff --git a/reactos/dll/win32/msi/record.c b/reactos/dll/win32/msi/record.c index 7bc82814b2e..fc30f793436 100644 --- a/reactos/dll/win32/msi/record.c +++ b/reactos/dll/win32/msi/record.c @@ -27,6 +27,7 @@ #include "winuser.h" #include "winerror.h" #include "wine/debug.h" +#include "wine/unicode.h" #include "msi.h" #include "msiquery.h" #include "msipriv.h" @@ -1016,7 +1017,7 @@ BOOL MSI_RecordsAreEqual(MSIRECORD *a, MSIRECORD *b) break; case MSIFIELD_WSTR: - if (lstrcmpW(a->fields[i].u.szwVal, b->fields[i].u.szwVal)) + if (strcmpW(a->fields[i].u.szwVal, b->fields[i].u.szwVal)) return FALSE; break; diff --git a/reactos/dll/win32/msi/registry.c b/reactos/dll/win32/msi/registry.c index e83490f5e36..017aa2405c9 100644 --- a/reactos/dll/win32/msi/registry.c +++ b/reactos/dll/win32/msi/registry.c @@ -1182,6 +1182,21 @@ UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL cr return RegOpenKeyW(HKEY_CLASSES_ROOT, keypath, key); } +UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode) +{ + WCHAR squished_pc[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szUpgradeCode)); + if (!squash_guid(szUpgradeCode, squished_pc)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(squished_pc)); + + sprintfW(keypath, szInstaller_ClassesUpgrade_fmt, squished_pc); + + return RegDeleteTreeW(HKEY_CLASSES_ROOT, keypath); +} + /************************************************************************* * MsiDecomposeDescriptorW [MSI.@] * @@ -1549,10 +1564,11 @@ UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct) sz = SQUISH_GUID_SIZE; r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL); if( r == ERROR_SUCCESS ) + { unsquash_guid(szValName, szProduct); - + TRACE("-> %s\n", debugstr_w(szProduct)); + } RegCloseKey(hkeyComp); - return r; } @@ -2140,7 +2156,7 @@ UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid, if (!szProductCode || !squash_guid(szProductCode, squished_pc)) return ERROR_INVALID_PARAMETER; - if (!lstrcmpW(szUserSid, szLocalSid)) + if (szUserSid && !strcmpW( szUserSid, szLocalSid )) return ERROR_INVALID_PARAMETER; if (dwContext & MSIINSTALLCONTEXT_MACHINE && szUserSid) diff --git a/reactos/dll/win32/msi/script.c b/reactos/dll/win32/msi/script.c index 4f223daa8b0..27bbee1afda 100644 --- a/reactos/dll/win32/msi/script.c +++ b/reactos/dll/win32/msi/script.c @@ -143,6 +143,7 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function /* Add the session object */ hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_ISVISIBLE); + if (FAILED(hr)) goto done; /* Pass the script to the engine */ hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL); diff --git a/reactos/dll/win32/msi/source.c b/reactos/dll/win32/msi/source.c index 8e4323a4711..881f3d26bf2 100644 --- a/reactos/dll/win32/msi/source.c +++ b/reactos/dll/win32/msi/source.c @@ -330,7 +330,6 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode, else size = lstrlenW(ptr); - size = lstrlenW(ptr); if (size >= *pcchDiskPrompt) r = ERROR_MORE_DATA; else if (szDiskPrompt) @@ -592,8 +591,8 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, if (rc != ERROR_SUCCESS) return rc; - if (!lstrcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ) || + !strcmpW( szProperty, INSTALLPROPERTY_DISKPROMPTW )) { rc = OpenMediaSubkey(sourcekey, &media, FALSE); if (rc != ERROR_SUCCESS) @@ -602,14 +601,14 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, return ERROR_SUCCESS; } - if (!lstrcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW )) szProperty = mediapack; RegQueryValueExW(media, szProperty, 0, 0, (LPBYTE)szValue, pcchValue); RegCloseKey(media); } - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDTYPEW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW ) || + !strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDTYPEW )) { rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0, NULL, &size); @@ -630,7 +629,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, return ERROR_SUCCESS; } - if (!lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDTYPEW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDTYPEW )) { if (*source != 'n' && *source != 'u' && *source != 'm') { @@ -662,7 +661,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, *pcchValue = lstrlenW(ptr); msi_free(source); } - else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0) + else if (!strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW )) { *pcchValue = *pcchValue * sizeof(WCHAR); rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0, @@ -815,22 +814,22 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, } property = szProperty; - if (!lstrcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW )) property = media_package; rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, dwContext, FALSE); if (rc != ERROR_SUCCESS) return rc; - if (lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW) && + if (strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW ) && dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL)) { RegCloseKey(sourcekey); return ERROR_INVALID_PARAMETER; } - if (!lstrcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) || - !lstrcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW)) + if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ) || + !strcmpW( szProperty, INSTALLPROPERTY_DISKPROMPTW )) { rc = OpenMediaSubkey(sourcekey, &media, TRUE); if (rc == ERROR_SUCCESS) @@ -839,7 +838,7 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, RegCloseKey(media); } } - else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0) + else if (!strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW )) { DWORD size = (lstrlenW(szValue) + 1) * sizeof(WCHAR); rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, @@ -847,7 +846,7 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, if (rc != ERROR_SUCCESS) rc = ERROR_UNKNOWN_PROPERTY; } - else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)) + else if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW )) { if (!(dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL))) rc = ERROR_INVALID_PARAMETER; @@ -1130,6 +1129,12 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid, RegCloseKey(sourcekey); return ERROR_FUNCTION_FAILED; } + if (rc != ERROR_SUCCESS) + { + ERR("can't open subkey %u\n", rc); + RegCloseKey(sourcekey); + return rc; + } postfix = (dwOptions & MSISOURCETYPE_NETWORK) ? szBackSlash : szForwardSlash; if (szSource[lstrlenW(szSource) - 1] == *postfix) diff --git a/reactos/dll/win32/msi/sql.tab.c b/reactos/dll/win32/msi/sql.tab.c index 72e230ca837..f70760278e5 100644 --- a/reactos/dll/win32/msi/sql.tab.c +++ b/reactos/dll/win32/msi/sql.tab.c @@ -2872,7 +2872,7 @@ static BOOL SQL_MarkPrimaryKeys( column_info **cols, found = FALSE; for( c = *cols, idx = 0; c && !found; c = c->next, idx++ ) { - if( lstrcmpW( k->column, c->column ) ) + if( strcmpW( k->column, c->column ) ) continue; c->type |= MSITYPE_KEY; found = TRUE; diff --git a/reactos/dll/win32/msi/sql.y b/reactos/dll/win32/msi/sql.y index 548a8782444..01217378534 100644 --- a/reactos/dll/win32/msi/sql.y +++ b/reactos/dll/win32/msi/sql.y @@ -950,7 +950,7 @@ static BOOL SQL_MarkPrimaryKeys( column_info **cols, found = FALSE; for( c = *cols, idx = 0; c && !found; c = c->next, idx++ ) { - if( lstrcmpW( k->column, c->column ) ) + if( strcmpW( k->column, c->column ) ) continue; c->type |= MSITYPE_KEY; found = TRUE; diff --git a/reactos/dll/win32/msi/string.c b/reactos/dll/win32/msi/string.c index 5644749392f..406803337f4 100644 --- a/reactos/dll/win32/msi/string.c +++ b/reactos/dll/win32/msi/string.c @@ -58,15 +58,22 @@ struct string_table UINT *sorted; /* index */ }; +static BOOL validate_codepage( UINT codepage ) +{ + if (codepage != CP_ACP && !IsValidCodePage( codepage )) + { + WARN("invalid codepage %u\n", codepage); + return FALSE; + } + return TRUE; +} + static string_table *init_stringtable( int entries, UINT codepage ) { string_table *st; - if (codepage != CP_ACP && !IsValidCodePage(codepage)) - { - ERR("invalid codepage %d\n", codepage); + if (!validate_codepage( codepage )) return NULL; - } st = msi_alloc( sizeof (string_table) ); if( !st ) @@ -162,7 +169,7 @@ static int find_insert_index( const string_table *st, UINT string_id ) while (low <= high) { i = (low + high) / 2; - c = lstrcmpW( st->strings[string_id].str, st->strings[st->sorted[i]].str ); + c = strcmpW( st->strings[string_id].str, st->strings[st->sorted[i]].str ); if (c < 0) high = i - 1; @@ -402,7 +409,7 @@ UINT msi_string2idW( const string_table *st, LPCWSTR str, UINT *id ) while (low <= high) { i = (low + high) / 2; - c = lstrcmpW( str, st->strings[st->sorted[i]].str ); + c = strcmpW( str, st->strings[st->sorted[i]].str ); if (c < 0) high = i - 1; @@ -671,3 +678,18 @@ err: return ret; } + +UINT msi_get_string_table_codepage( const string_table *st ) +{ + return st->codepage; +} + +UINT msi_set_string_table_codepage( string_table *st, UINT codepage ) +{ + if (validate_codepage( codepage )) + { + st->codepage = codepage; + return ERROR_SUCCESS; + } + return ERROR_FUNCTION_FAILED; +} diff --git a/reactos/dll/win32/msi/table.c b/reactos/dll/win32/msi/table.c index 3e456ed56c4..14f4d307ddd 100644 --- a/reactos/dll/win32/msi/table.c +++ b/reactos/dll/win32/msi/table.c @@ -156,7 +156,7 @@ LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) if( !bTable ) count = lstrlenW( in )+2; - out = msi_alloc( count*sizeof(WCHAR) ); + if (!(out = msi_alloc( count*sizeof(WCHAR) ))) return NULL; p = out; if( bTable ) @@ -512,7 +512,7 @@ static MSITABLE *find_cached_table( MSIDATABASE *db, LPCWSTR name ) MSITABLE *t; LIST_FOR_EACH_ENTRY( t, &db->tables, MSITABLE, entry ) - if( !lstrcmpW( name, t->name ) ) + if( !strcmpW( name, t->name ) ) return t; return NULL; @@ -731,7 +731,7 @@ static UINT get_table( MSIDATABASE *db, LPCWSTR name, MSITABLE **table_ret ) table->persistent = MSICONDITION_TRUE; lstrcpyW( table->name, name ); - if ( !lstrcmpW(name, szTables) || !lstrcmpW(name, szColumns) ) + if ( !strcmpW( name, szTables ) || !strcmpW( name, szColumns ) ) table->persistent = MSICONDITION_NONE; r = table_get_column_info( db, name, &table->colinfo, &table->col_count); @@ -766,7 +766,8 @@ static UINT read_table_int(BYTE *const *data, UINT row, UINT col, UINT bytes) static UINT save_table( MSIDATABASE *db, const MSITABLE *t, UINT bytes_per_strref ) { BYTE *rawdata = NULL; - UINT rawsize, r, i, j, row_size, row_count; + UINT rawsize, i, j, row_size, row_count; + UINT r = ERROR_FUNCTION_FAILED; /* Nothing to do for non-persistent tables */ if( t->persistent == MSICONDITION_FALSE ) @@ -816,7 +817,6 @@ static UINT save_table( MSIDATABASE *db, const MSITABLE *t, UINT bytes_per_strre if (id > 1 << bytes_per_strref * 8) { ERR("string id %u out of range\n", id); - r = ERROR_FUNCTION_FAILED; goto err; } } @@ -864,12 +864,12 @@ static UINT get_defaulttablecolumns( MSIDATABASE *db, LPCWSTR name, TRACE("%s\n", debugstr_w(name)); - if (!lstrcmpW( name, szTables )) + if (!strcmpW( name, szTables )) { p = _Tables_cols; n = 1; } - else if (!lstrcmpW( name, szColumns )) + else if (!strcmpW( name, szColumns )) { p = _Columns_cols; n = 4; @@ -1037,11 +1037,8 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ) UINT r, table_id, i; MSITABLE *table; - static const WCHAR szStreams[] = {'_','S','t','r','e','a','m','s',0}; - static const WCHAR szStorages[] = {'_','S','t','o','r','a','g','e','s',0}; - - if( !lstrcmpW( name, szTables ) || !lstrcmpW( name, szColumns ) || - !lstrcmpW( name, szStreams ) || !lstrcmpW( name, szStorages ) ) + if( !strcmpW( name, szTables ) || !strcmpW( name, szColumns ) || + !strcmpW( name, szStreams ) || !strcmpW( name, szStorages ) ) return TRUE; r = msi_string2idW( db->strings, name, &table_id ); @@ -1146,6 +1143,8 @@ static UINT msi_stream_name( const MSITABLEVIEW *tv, UINT row, LPWSTR *pstname ) type = tv->columns[i].type; if ( type & MSITYPE_KEY ) { + WCHAR number[0x20]; + r = TABLE_fetch_int( view, row, i+1, &ival ); if ( r != ERROR_SUCCESS ) goto err; @@ -1162,7 +1161,6 @@ static UINT msi_stream_name( const MSITABLEVIEW *tv, UINT row, LPWSTR *pstname ) else { static const WCHAR fmt[] = { '%','d',0 }; - WCHAR number[0x20]; UINT n = bytes_per_column( tv->db, &tv->columns[i], LONG_STR_BYTES ); switch( n ) @@ -1346,10 +1344,13 @@ static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT else if ( columninfo.type & MSITYPE_STRING ) { LPCWSTR sval = MSI_RecordGetString( rec, iField ); - - r = msi_string2idW(tv->db->strings, sval, pvalue); - if (r != ERROR_SUCCESS) - return ERROR_NOT_FOUND; + if (sval) + { + r = msi_string2idW(tv->db->strings, sval, pvalue); + if (r != ERROR_SUCCESS) + return ERROR_NOT_FOUND; + } + else *pvalue = 0; } else if ( bytes_per_column( tv->db, &columninfo, LONG_STR_BYTES ) == 2 ) { @@ -1432,7 +1433,6 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI LPCWSTR sval = MSI_RecordGetString( rec, i + 1 ); val = msi_addstringW( tv->db->strings, sval, -1, 1, persistent ? StringPersistent : StringNonPersistent ); - } else { @@ -1630,6 +1630,8 @@ static int compare_record( MSITABLEVIEW *tv, UINT row, MSIRECORD *rec ) for (i = 0; i < tv->num_cols; i++ ) { + if (!(tv->columns[i].type & MSITYPE_KEY)) continue; + r = get_table_value_from_record( tv, rec, i + 1, &ivalue ); if (r != ERROR_SUCCESS) return 1; @@ -1774,6 +1776,9 @@ static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) if (row != new_row + 1) return ERROR_FUNCTION_FAILED; + if(tv->order) + new_row = tv->order->reorder[new_row]; + return TABLE_set_row(view, new_row, rec, (1 << tv->num_cols) - 1); } @@ -2099,7 +2104,7 @@ static UINT TABLE_add_column(struct tagMSIVIEW *view, LPCWSTR table, UINT number msitable = find_cached_table(tv->db, table); for (i = 0; i < msitable->col_count; i++) { - if (!lstrcmpW(msitable->colinfo[i].colname, column)) + if (!strcmpW( msitable->colinfo[i].colname, column )) { InterlockedIncrement(&msitable->colinfo[i].ref_count); break; @@ -2340,14 +2345,11 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view ) MSITABLEVIEW *tv ; UINT r, sz; - static const WCHAR Streams[] = {'_','S','t','r','e','a','m','s',0}; - static const WCHAR Storages[] = {'_','S','t','o','r','a','g','e','s',0}; - TRACE("%p %s %p\n", db, debugstr_w(name), view ); - if ( !lstrcmpW( name, Streams ) ) + if ( !strcmpW( name, szStreams ) ) return STREAMS_CreateView( db, view ); - else if ( !lstrcmpW( name, Storages ) ) + else if ( !strcmpW( name, szStorages ) ) return STORAGES_CreateView( db, view ); sz = sizeof *tv + lstrlenW(name)*sizeof name[0] ; @@ -2593,7 +2595,7 @@ static void dump_record( MSIRECORD *rec ) n = MSI_RecordGetFieldCount( rec ); for( i=1; i<=n; i++ ) { - LPCWSTR sval = MSI_RecordGetString( rec, i ); + LPCWSTR sval; if( MSI_RecordIsNull( rec, i ) ) TRACE("row -> []\n"); @@ -2634,15 +2636,19 @@ static UINT* msi_record_to_row( const MSITABLEVIEW *tv, MSIRECORD *rec ) ! MSITYPE_IS_BINARY(tv->columns[i].type) ) { str = MSI_RecordGetString( rec, i+1 ); - r = msi_string2idW( tv->db->strings, str, &data[i] ); - - /* if there's no matching string in the string table, - these keys can't match any record, so fail now. */ - if( ERROR_SUCCESS != r ) + if (str) { - msi_free( data ); - return NULL; + r = msi_string2idW( tv->db->strings, str, &data[i] ); + + /* if there's no matching string in the string table, + these keys can't match any record, so fail now. */ + if (r != ERROR_SUCCESS) + { + msi_free( data ); + return NULL; + } } + else data[i] = 0; } else { @@ -2818,7 +2824,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, UINT number = MSI_NULL_INTEGER; UINT row = 0; - if (!lstrcmpW( name, szColumns )) + if (!strcmpW( name, szColumns )) { MSI_RecordGetStringW( rec, 1, table, &sz ); number = MSI_RecordGetInteger( rec, 2 ); @@ -2830,7 +2836,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, if ( number == MSI_NULL_INTEGER ) { /* reset the column number on a new table */ - if (lstrcmpW( coltable, table )) + if (strcmpW( coltable, table )) { colcol = 0; lstrcpyW( coltable, table ); @@ -2876,7 +2882,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, WARN("failed to insert row %u\n", r); } - if (number != MSI_NULL_INTEGER && !lstrcmpW( name, szColumns )) + if (number != MSI_NULL_INTEGER && !strcmpW( name, szColumns )) msi_update_table_columns( db, table ); msiobj_release( &rec->hdr ); @@ -2938,8 +2944,8 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg ) if ( name[0] != 0x4840 ) continue; - if ( !lstrcmpW( name+1, szStringPool ) || - !lstrcmpW( name+1, szStringData ) ) + if ( !strcmpW( name+1, szStringPool ) || + !strcmpW( name+1, szStringData ) ) continue; transform = msi_alloc_zero( sizeof(TRANSFORMDATA) ); @@ -2950,9 +2956,9 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg ) transform->name = strdupW( name + 1 ); - if ( !lstrcmpW( transform->name, szTables ) ) + if ( !strcmpW( transform->name, szTables ) ) tables = transform; - else if (!lstrcmpW( transform->name, szColumns ) ) + else if (!strcmpW( transform->name, szColumns ) ) columns = transform; TRACE("transform contains stream %s\n", debugstr_w(name)); @@ -2990,8 +2996,8 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg ) { transform = LIST_ENTRY( list_head( &transforms ), TRANSFORMDATA, entry ); - if ( lstrcmpW( transform->name, szColumns ) && - lstrcmpW( transform->name, szTables ) && + if ( strcmpW( transform->name, szColumns ) && + strcmpW( transform->name, szTables ) && ret == ERROR_SUCCESS ) { ret = msi_table_load_transform( db, stg, strings, transform, bytes_per_strref ); diff --git a/reactos/dll/win32/msi/where.c b/reactos/dll/win32/msi/where.c index 4c4db491474..35a6074a650 100644 --- a/reactos/dll/win32/msi/where.c +++ b/reactos/dll/win32/msi/where.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winerror.h" #include "wine/debug.h" +#include "wine/unicode.h" #include "msi.h" #include "msiquery.h" #include "objbase.h" @@ -306,7 +307,7 @@ static UINT STRCMP_Evaluate( MSIWHEREVIEW *wv, UINT row, const struct expr *cond else if( r_str && ! l_str ) sr = -1; else - sr = lstrcmpW( l_str, r_str ); + sr = strcmpW( l_str, r_str ); *val = ( cond->u.expr.op == OP_EQ && ( sr == 0 ) ) || ( cond->u.expr.op == OP_NE && ( sr != 0 ) ); @@ -327,11 +328,15 @@ static UINT WHERE_evaluate( MSIWHEREVIEW *wv, UINT row, { case EXPR_COL_NUMBER: r = wv->table->ops->fetch_int( wv->table, row, cond->u.col_number, &tval ); + if( r != ERROR_SUCCESS ) + return r; *val = tval - 0x8000; return ERROR_SUCCESS; case EXPR_COL_NUMBER32: r = wv->table->ops->fetch_int( wv->table, row, cond->u.col_number, &tval ); + if( r != ERROR_SUCCESS ) + return r; *val = tval - 0x80000000; return r; From 75629abccd410996e1688818278d20ce6d4c1cfe Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 20 Mar 2011 10:10:52 +0000 Subject: [PATCH 35/90] [MSI] Fix build according to Christoph recommandations svn path=/trunk/; revision=51097 --- reactos/dll/win32/msi/msi.rc | 3 --- 1 file changed, 3 deletions(-) diff --git a/reactos/dll/win32/msi/msi.rc b/reactos/dll/win32/msi/msi.rc index c980fa891d2..985304c348d 100644 --- a/reactos/dll/win32/msi/msi.rc +++ b/reactos/dll/win32/msi/msi.rc @@ -66,9 +66,6 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* @makedep: msiserver.tlb */ 1 TYPELIB msiserver.tlb -/* @makedep: msiserver.rgs */ -1 WINE_REGISTRY msiserver.rgs - /* @makedep: instadvert.bmp */ 0x1001 BITMAP instadvert.bmp From 099a888ea2fe6b746200c728109514def822972e Mon Sep 17 00:00:00 2001 From: Olaf Siejka Date: Sun, 20 Mar 2011 11:25:34 +0000 Subject: [PATCH 36/90] [CACLS] - Danish translation by Wilhelm Wiens [RAPPS] - Polish translations of SumatraPDF entry by Adam Stachowicz [SETUP] - Polish translation of 'VBR only' in the reactos.exe svn path=/trunk/; revision=51098 --- reactos/base/applications/cacls/lang/da-DA.rc | 79 +++++++++++++++++++ reactos/base/applications/cacls/rsrc.rc | 1 + .../applications/rapps/rapps/sumatrapdf.txt | 3 + reactos/base/setup/reactos/lang/pl-PL.rc | 4 +- 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 reactos/base/applications/cacls/lang/da-DA.rc diff --git a/reactos/base/applications/cacls/lang/da-DA.rc b/reactos/base/applications/cacls/lang/da-DA.rc new file mode 100644 index 00000000000..7663dae602d --- /dev/null +++ b/reactos/base/applications/cacls/lang/da-DA.rc @@ -0,0 +1,79 @@ +/* + * German language file by Daniel Reimer 2006-06-15 + */ + +LANGUAGE LANG_DANISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +BEGIN + +IDS_HELP, "Ćndringer fil-ACL'er (Access Control List) eller viser dem.\n\n\ +CACLS Filenavn [/T] [/E] [/C] [/G Bruger:Adgang] [/R Bruger [...]]\n\ + [/P Bruger:Adgang [...]] [/D Bruger [...]]\n\ + Filnavn Viser ACL'er for angivet filer.\n\ + /T Ćndre ACL'er for angivene filer i mapper\n\ + og alle undermapper.\n\ + /E Bearbejde ACL i stedet for at erstatte.\n\ + /C Forandre ACL'er ved adgangfejl videre.\n\ + /G Bruger:Adgang Tillade angivene adgangsformer.\n\ + Adgang kan vćre: R lćse\n\ + W skrive\n\ + C ćndre (At skrive)\n\ + F Fuld adgang\n\ + /R Bruger Fjerne adgangsrette af brugeren (kun gyldig med /E).\n\ + /P Bruger:Adgang Erstatte adgangsretterne af brugeren.\n\ + Adgang kan vćre: N Ingen\n\ + R Lćse\n\ + W Skrive\n\ + C ćndre (Skrive)\n\ + F fuld adgang\n\ + /D Bruger Forbyde adgang for brugeren.\n\ +Mellemrum(Wildcards) bliver understřttet i filenavn.\n\ +Man kan angive flere bruger i en kommando.\n\n\ +Forkortninger:\n\ + CI - Container overtagelse.\n\ + ACE-Bidragen bliver overtaget fra mapperne.\n\ + OI - Objekt overtagelse.\n\ + ACE-Bidragen bliver overtaget fra filerne.\n\ + IO - Kun overtagelse.\n\ + ACE'ens egenskab passer ikke sammen med\n\ + de aktuelle filer/mapper.\n" + +IDS_ABBR_CI, "(CI)" +IDS_ABBR_OI, "(OI)" +IDS_ABBR_IO, "(IO)" +IDS_ABBR_FULL, "F" +IDS_ABBR_READ, "R" +IDS_ABBR_WRITE, "W" +IDS_ABBR_CHANGE, "C" +IDS_ABBR_NONE, "N" +IDS_ALLOW, "" +IDS_DENY, "(DENY)" +IDS_SPECIAL_ACCESS, "(special access:)" +IDS_GENERIC_READ, "GENERIC_READ" +IDS_GENERIC_WRITE, "GENERIC_WRITE" +IDS_GENERIC_EXECUTE, "GENERIC_EXECUTE" +IDS_GENERIC_ALL, "GENERIC_ALL" +IDS_FILE_GENERIC_EXECUTE, "FILE_GENERIC_EXECUTE" +IDS_FILE_GENERIC_READ, "FILE_GENERIC_READ" +IDS_FILE_GENERIC_WRITE, "FILE_GENERIC_WRITE" +IDS_FILE_READ_DATA, "FILE_READ_DATA" +IDS_FILE_WRITE_DATA, "FILE_WRITE_DATA" +IDS_FILE_APPEND_DATA, "FILE_APPEND_DATA" +IDS_FILE_READ_EA, "FILE_READ_EA" +IDS_FILE_WRITE_EA, "FILE_WRITE_EA" +IDS_FILE_EXECUTE, "FILE_EXECUTE" +IDS_FILE_DELETE_CHILD, "FILE_DELETE_CHILD" +IDS_FILE_READ_ATTRIBUTES, "FILE_READ_ATTRIBUTES" +IDS_FILE_WRITE_ATTRIBUTES, "FILE_WRITE_ATTRIBUTES" +IDS_MAXIMUM_ALLOWED, "MAXIMUM_ALLOWED" +IDS_ACCESS_SYSTEM_SECURITY, "ACCESS_SYSTEM_SECURITY" +IDS_SPECIFIC_RIGHTS_ALL, "SPECIFIC_RIGHTS_ALL" +IDS_STANDARD_RIGHTS_REQUIRED, "STANDARD_RIGHTS_REQUIRED" +IDS_SYNCHRONIZE, "SYNCHRONIZE" +IDS_WRITE_OWNER, "WRITE_OWNER" +IDS_WRITE_DAC, "WRITE_DAC" +IDS_READ_CONTROL, "READ_CONTROL" +IDS_DELETE, "DELETE" +IDS_STANDARD_RIGHTS_ALL, "STANDARD_RIGHTS_ALL" +END diff --git a/reactos/base/applications/cacls/rsrc.rc b/reactos/base/applications/cacls/rsrc.rc index cf19989a441..b392e1ea202 100644 --- a/reactos/base/applications/cacls/rsrc.rc +++ b/reactos/base/applications/cacls/rsrc.rc @@ -4,6 +4,7 @@ #include "lang/bg-BG.rc" #include "lang/ca-ES.rc" #include "lang/cs-CZ.rc" +#include "lang/da-DA.rc" #include "lang/de-DE.rc" #include "lang/el-GR.rc" #include "lang/en-US.rc" diff --git a/reactos/base/applications/rapps/rapps/sumatrapdf.txt b/reactos/base/applications/rapps/rapps/sumatrapdf.txt index abb9bc6926e..1e142ed113a 100644 --- a/reactos/base/applications/rapps/rapps/sumatrapdf.txt +++ b/reactos/base/applications/rapps/rapps/sumatrapdf.txt @@ -16,3 +16,6 @@ Description = Sumatra PDF ist ein freies, schlankes, Open-Source PDF-Anzeigeprog [Section.0410] Description = Sumatra PDF è un visualizzatore di file PDF. E' molto leggero ed è open source. + +[Section.0415] +Description = Sumatra PDF to maĹ‚y, darmowy, otwarty czytnik PDF. diff --git a/reactos/base/setup/reactos/lang/pl-PL.rc b/reactos/base/setup/reactos/lang/pl-PL.rc index 31c951397cf..2a3a4ea6bad 100644 --- a/reactos/base/setup/reactos/lang/pl-PL.rc +++ b/reactos/base/setup/reactos/lang/pl-PL.rc @@ -4,6 +4,7 @@ * https://sourceforge.net/projects/reactospl * http://rogers.cyberdusk.pl/ * update - niski (bjauy@o2.pl) + * updated by Caemyr (Olaf Siejka), Mar 2011 */ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT @@ -97,7 +98,8 @@ BEGIN CONTROL "Instalacja bootloadera", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41 - CONTROL "Wgraj bootloader na dysk twardy (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 + CONTROL "Wgraj bootloader na dysk twardy (MBR i VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 + CONTROL "Wgraj bootloader na dysk twardy (tylko VBR)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11 CONTROL "Pomiń wgrywanie bootloadera", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11 PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE PUSHBUTTON "&Anuluj", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE From 66f5809036c94366dba06797f9738cebcaee16a7 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 20 Mar 2011 11:29:51 +0000 Subject: [PATCH 37/90] - Fix a miss var for testing. svn path=/trunk/; revision=51099 --- reactos/subsystems/win32/win32k/ntuser/simplecall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/simplecall.c b/reactos/subsystems/win32/win32k/ntuser/simplecall.c index 87d8c07dc3a..d4a1a14f403 100644 --- a/reactos/subsystems/win32/win32k/ntuser/simplecall.c +++ b/reactos/subsystems/win32/win32k/ntuser/simplecall.c @@ -187,7 +187,7 @@ NtUserCallOneParam( RtlZeroMemory(psmwp->acvr, count * sizeof(CVR)); psmwp->bHandle = TRUE; psmwp->ccvr = 0; // actualCount - psmwp->ccvrAlloc = Param; // suggestedCount + psmwp->ccvrAlloc = count; // suggestedCount RETURN((DWORD_PTR)hDwp); } From 5177b0a967fc192a1ad42a58b5776ae4935ba707 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 20 Mar 2011 12:59:07 +0000 Subject: [PATCH 38/90] [User32_ApiTests] - Patch by Thomas Faber: Tests for new DeferWindowPos implementation. See bug 6025. svn path=/trunk/; revision=51100 --- rostests/apitests/user32/CMakeLists.txt | 1 + rostests/apitests/user32/DeferWindowPos.c | 170 ++++++++++++++++++ rostests/apitests/user32/testlist.c | 2 + .../apitests/user32/user32_apitest.rbuild | 1 + 4 files changed, 174 insertions(+) create mode 100644 rostests/apitests/user32/DeferWindowPos.c diff --git a/rostests/apitests/user32/CMakeLists.txt b/rostests/apitests/user32/CMakeLists.txt index e11fdf4558c..9fc9374db52 100644 --- a/rostests/apitests/user32/CMakeLists.txt +++ b/rostests/apitests/user32/CMakeLists.txt @@ -9,6 +9,7 @@ list(APPEND SOURCE GetSystemMetrics.c GetIconInfo.c GetPeekMessage.c + DeferWindowPos.c testlist.c user32_apitest.rc) diff --git a/rostests/apitests/user32/DeferWindowPos.c b/rostests/apitests/user32/DeferWindowPos.c new file mode 100644 index 00000000000..b9a3d725c33 --- /dev/null +++ b/rostests/apitests/user32/DeferWindowPos.c @@ -0,0 +1,170 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for DeferWindowPos function family + * PROGRAMMERS: Thomas Faber + */ + +#include +#include +#include + +#define ok_windowpos(hwnd, x, y, w, h, wnd) do { RECT rt; GetWindowRect(hwnd, &rt); \ + ok(rt.left == (x) && rt.top == (y) && rt.right == (x)+(w) && rt.bottom == (y)+(h), \ + "Unexpected %s position: (%ld, %ld) - (%ld, %ld)\n", wnd, rt.left, rt.top, rt.right, rt.bottom); } while (0) + +#define ok_lasterr(err, s) ok(GetLastError() == (err), "%s error = %lu\n", s, GetLastError()) + +static void Test_DeferWindowPos(HWND hWnd, HWND hWnd2) +{ + HDWP hDwp; + BOOL ret; + + /* close invalid handles */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + ret = EndDeferWindowPos(NULL); + ok(ret == 0, "EndDeferWindowPos succeeded with invalid handle\n"); + ok_lasterr(ERROR_INVALID_DWP_HANDLE, "EndDeferWindowPos"); + + SetLastError(DNS_ERROR_RCODE_NXRRSET); + ret = EndDeferWindowPos((HDWP)-1); + ok(ret == 0, "EndDeferWindowPos succeeded with invalid handle\n"); + ok_lasterr(ERROR_INVALID_DWP_HANDLE, "EndDeferWindowPos"); + + /* negative window count */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(-1); + ok(hDwp == NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(ERROR_INVALID_PARAMETER, "BeginDeferWindowPos"); + + /* zero windows */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(0); + ok(hDwp != NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos"); + ret = EndDeferWindowPos(hDwp); + ok(ret != 0, "EndDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "EndDeferWindowPos"); + + /* more windows than expected */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(0); + ok(hDwp != NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + ret = EndDeferWindowPos(hDwp); + ok(ret != 0, "EndDeferWindowPos failed\n"); + ok(GetLastError() == ERROR_SUCCESS /* win7 sp1/x64 */ + || GetLastError() == ERROR_INVALID_WINDOW_HANDLE /* 2k3 sp1/x86 */, + "EndDeferWindowPos error = %lu\n", GetLastError()); + ok_windowpos(hWnd, 10, 20, 200, 210, "Window 1"); + + /* more windows than expected 2 */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(1); + ok(hDwp != NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd, NULL, 30, 20, 190, 195, SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd2, NULL, 20, 30, 195, 190, SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + ret = EndDeferWindowPos(hDwp); + ok(ret != 0, "EndDeferWindowPos failed\n"); + ok_lasterr(ERROR_SUCCESS, "EndDeferWindowPos"); + ok_windowpos(hWnd, 30, 20, 190, 195, "Window 1"); + ok_windowpos(hWnd2, 20, 30, 195, 190, "Window 2"); + + /* fewer windows than expected */ + MoveWindow(hWnd, 10, 20, 200, 210, FALSE); + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(2); + ok(hDwp != NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd, NULL, 20, 10, 210, 200, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + ret = EndDeferWindowPos(hDwp); + ok(ret != 0, "EndDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "EndDeferWindowPos"); + ok_windowpos(hWnd, 10, 20, 200, 210, "Window 1"); + + /* no operation, 1 window */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(1); + ok(hDwp != NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd, NULL, 20, 10, 210, 200, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + ret = EndDeferWindowPos(hDwp); + ok(ret != 0, "EndDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "EndDeferWindowPos"); + ok_windowpos(hWnd, 10, 20, 200, 210, "Window 1"); + + /* same window twice */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(2); + ok(hDwp != NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd, NULL, 80, 90, 220, 210, SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd, NULL, 100, 110, 230, 250, SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + ret = EndDeferWindowPos(hDwp); + ok(ret != 0, "EndDeferWindowPos failed\n"); + ok_lasterr(ERROR_SUCCESS, "EndDeferWindowPos"); + ok_windowpos(hWnd, 100, 110, 230, 250, "Window 1"); + + /* move & resize operation, 1 window */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(1); + ok(hDwp != NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd, NULL, 20, 10, 210, 200, SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + ret = EndDeferWindowPos(hDwp); + ok(ret != 0, "EndDeferWindowPos failed\n"); + ok_lasterr(ERROR_SUCCESS, "EndDeferWindowPos"); + ok_windowpos(hWnd, 20, 10, 210, 200, "Window 1"); + + /* move & resize operation, 2 windows */ + SetLastError(DNS_ERROR_RCODE_NXRRSET); + hDwp = BeginDeferWindowPos(2); + ok(hDwp != NULL, "BeginDeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd, NULL, 50, 60, 230, 240, SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + hDwp = DeferWindowPos(hDwp, hWnd2, NULL, 70, 80, 250, 260, SWP_NOZORDER); + ok(hDwp != NULL, "DeferWindowPos failed\n"); + ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos"); + ret = EndDeferWindowPos(hDwp); + ok(ret != 0, "EndDeferWindowPos failed\n"); + ok_lasterr(ERROR_SUCCESS, "EndDeferWindowPos"); + ok_windowpos(hWnd, 50, 60, 230, 240, "Window 1"); + ok_windowpos(hWnd2, 70, 80, 250, 260, "Window 2"); +} + +START_TEST(DeferWindowPos) +{ + HWND hWnd = CreateWindowExW(0, L"EDIT", L"abc", 0, 10, 20, + 200, 210, NULL, NULL, GetModuleHandle(NULL), NULL); + HWND hWnd2 = CreateWindowExW(0, L"EDIT", L"def", 0, 30, 40, + 220, 230, NULL, NULL, GetModuleHandle(NULL), NULL); + ok(hWnd != NULL, "CreateWindow failed\n"); + ok(hWnd2 != NULL, "CreateWindow failed\n"); + ok_windowpos(hWnd, 10, 20, 200, 210, "Window 1"); + ok_windowpos(hWnd2, 30, 40, 220, 230, "Window 2"); + + Test_DeferWindowPos(hWnd, hWnd2); + + DestroyWindow(hWnd2); + DestroyWindow(hWnd); +} diff --git a/rostests/apitests/user32/testlist.c b/rostests/apitests/user32/testlist.c index b37d7ca0607..f89be66ed15 100644 --- a/rostests/apitests/user32/testlist.c +++ b/rostests/apitests/user32/testlist.c @@ -12,6 +12,7 @@ extern void func_ScrollWindowEx(void); extern void func_GetSystemMetrics(void); extern void func_GetIconInfo(void); extern void func_GetPeekMessage(void); +extern void func_DeferWindowPos(void); const struct test winetest_testlist[] = { @@ -22,6 +23,7 @@ const struct test winetest_testlist[] = { "GetSystemMetrics", func_GetSystemMetrics }, { "GetIconInfo", func_GetIconInfo }, { "GetPeekMessage", func_GetPeekMessage }, + { "DeferWindowPos", func_DeferWindowPos }, { 0, 0 } }; diff --git a/rostests/apitests/user32/user32_apitest.rbuild b/rostests/apitests/user32/user32_apitest.rbuild index 8aaa1dfb4ee..6f5489c31d2 100644 --- a/rostests/apitests/user32/user32_apitest.rbuild +++ b/rostests/apitests/user32/user32_apitest.rbuild @@ -17,6 +17,7 @@ GetSystemMetrics.c GetIconInfo.c GetPeekMessage.c + DeferWindowPos.c From 508ce4d9f89858d529a143e713d6450a751d57b2 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Sun, 20 Mar 2011 14:28:12 +0000 Subject: [PATCH 39/90] [win32k] - Fix disconnecting from a desktop when IntSetThreadDesktop gets NULL parameter svn path=/trunk/; revision=51101 --- .../subsystems/win32/win32k/ntuser/desktop.c | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index f56d587f648..0a240ad7772 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -1798,7 +1798,7 @@ BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure) { - PDESKTOP DesktopObject, OldDesktop; + PDESKTOP DesktopObject = NULL, OldDesktop; HDESK hOldDesktop; PTHREADINFO W32Thread; NTSTATUS Status; @@ -1809,24 +1809,28 @@ IntSetThreadDesktop(IN HDESK hDesktop, MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess); W32Thread = PsGetCurrentThreadWin32Thread(); - /* Validate the new desktop. */ - Status = IntValidateDesktopHandle( - hDesktop, - UserMode, - 0, - &DesktopObject); - - if (!NT_SUCCESS(Status)) + if(hDesktop != NULL) { - DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); - return FALSE; - } + /* Validate the new desktop. */ + Status = IntValidateDesktopHandle( + hDesktop, + UserMode, + 0, + &DesktopObject); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Validation of desktop handle (0x%X) failed\n", hDesktop); + return FALSE; + } + + if (W32Thread->rpdesk == DesktopObject) + { + /* Nothing to do */ + ObDereferenceObject(DesktopObject); + return TRUE; + } - if (W32Thread->rpdesk == DesktopObject) - { - /* Nothing to do */ - ObDereferenceObject(DesktopObject); - return TRUE; } if (!IsListEmpty(&W32Thread->WindowListHead)) From 01ecf02e26cfef98698c80acf26ad50a9c517e8e Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 21 Mar 2011 02:20:24 +0000 Subject: [PATCH 40/90] [Win32k] - Setup RectInRegion for internal use. svn path=/trunk/; revision=51102 --- .../subsystems/win32/win32k/include/region.h | 1 + .../subsystems/win32/win32k/objects/rect.c | 1 - .../subsystems/win32/win32k/objects/region.c | 33 ++++++++++++------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/region.h b/reactos/subsystems/win32/win32k/include/region.h index 5ad6e2cb52f..a7e531dff8b 100644 --- a/reactos/subsystems/win32/win32k/include/region.h +++ b/reactos/subsystems/win32/win32k/include/region.h @@ -44,6 +44,7 @@ INT APIENTRY IntGdiGetRgnBox(HRGN, RECTL*); BOOL FASTCALL IntGdiPaintRgn(PDC, HRGN ); HRGN FASTCALL IntCreatePolyPolygonRgn(PPOINT, PULONG, INT, INT); INT FASTCALL IntGdiOffsetRgn(PROSRGNDATA,INT,INT); +BOOL FASTCALL IntRectInRegion(HRGN,LPRECTL); INT FASTCALL IntGdiCombineRgn(PROSRGNDATA, PROSRGNDATA, PROSRGNDATA, INT); INT FASTCALL REGION_Complexity(PROSRGNDATA); diff --git a/reactos/subsystems/win32/win32k/objects/rect.c b/reactos/subsystems/win32/win32k/objects/rect.c index e3012185ca7..9fd5cdaefc6 100644 --- a/reactos/subsystems/win32/win32k/objects/rect.c +++ b/reactos/subsystems/win32/win32k/objects/rect.c @@ -16,7 +16,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* $Id$ */ #include diff --git a/reactos/subsystems/win32/win32k/objects/region.c b/reactos/subsystems/win32/win32k/objects/region.c index d1b00441065..d0bd3bafc61 100644 --- a/reactos/subsystems/win32/win32k/objects/region.c +++ b/reactos/subsystems/win32/win32k/objects/region.c @@ -3204,6 +3204,27 @@ IntCreatePolyPolygonRgn( return hrgn; } +BOOL +FASTCALL +IntRectInRegion( + HRGN hRgn, + LPRECTL rc +) +{ + PROSRGNDATA Rgn; + BOOL Ret; + + if (!(Rgn = RGNOBJAPI_Lock(hRgn, NULL))) + { + return ERROR; + } + + Ret = REGION_RectInRegion(Rgn, rc); + RGNOBJAPI_Unlock(Rgn); + return Ret; +} + + // // NtGdi Exported Functions // @@ -3765,16 +3786,9 @@ NtGdiRectInRegion( LPRECTL unsaferc ) { - PROSRGNDATA Rgn; RECTL rc = {0}; - BOOL Ret; NTSTATUS Status = STATUS_SUCCESS; - if (!(Rgn = RGNOBJAPI_Lock(hRgn, NULL))) - { - return ERROR; - } - _SEH2_TRY { ProbeForRead(unsaferc, sizeof(RECT), 1); @@ -3788,15 +3802,12 @@ NtGdiRectInRegion( if (!NT_SUCCESS(Status)) { - RGNOBJAPI_Unlock(Rgn); SetLastNtError(Status); DPRINT1("NtGdiRectInRegion: bogus rc\n"); return ERROR; } - Ret = REGION_RectInRegion(Rgn, &rc); - RGNOBJAPI_Unlock(Rgn); - return Ret; + return IntRectInRegion(hRgn, &rc); } BOOL From 073c778dcb1da6d2bb952d3dda7569940a8cf920 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 14:07:29 +0000 Subject: [PATCH 41/90] Don't destroy ImageList used by ListView if control was created without LVS_SHAREIMAGELISTS flag Fixes crashes when closing RegEdit, RApps and hardware tab in mouse settings. svn path=/trunk/; revision=51103 --- reactos/base/applications/rapps/winmain.c | 10 +- reactos/base/applications/regedit/childwnd.c | 160 +++++++++---------- reactos/dll/cpl/input/settings.c | 22 ++- 3 files changed, 100 insertions(+), 92 deletions(-) diff --git a/reactos/base/applications/rapps/winmain.c b/reactos/base/applications/rapps/winmain.c index 33e6f6f9e0a..9f6a0fc65f7 100644 --- a/reactos/base/applications/rapps/winmain.c +++ b/reactos/base/applications/rapps/winmain.c @@ -10,7 +10,6 @@ HWND hMainWnd; HINSTANCE hInst; -HIMAGELIST hImageListView = NULL; HIMAGELIST hImageTreeView = NULL; INT SelectedEnumType = ENUM_ALL_COMPONENTS; SETTINGS_INFO SettingsInfo; @@ -168,8 +167,8 @@ UpdateApplicationsList(INT EnumType) { WCHAR szBuffer1[MAX_STR_LEN], szBuffer2[MAX_STR_LEN]; HICON hIcon; + HIMAGELIST hImageListView; - if (hImageListView) ImageList_Destroy(hImageListView); (VOID) ListView_DeleteAllItems(hListView); /* Create image list */ @@ -208,7 +207,11 @@ UpdateApplicationsList(INT EnumType) } /* Set image list for ListView */ - (VOID) ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL); + hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL); + + /* Destroy old image list */ + if (hImageListView) + ImageList_Destroy(hImageListView); SelectedEnumType = EnumType; @@ -725,7 +728,6 @@ MainWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) FreeAvailableAppList(); if (IS_INSTALLED_ENUM(SelectedEnumType)) FreeInstalledAppList(); - if (hImageListView) ImageList_Destroy(hImageListView); if (hImageTreeView) ImageList_Destroy(hImageTreeView); PostQuitMessage(0); diff --git a/reactos/base/applications/regedit/childwnd.c b/reactos/base/applications/regedit/childwnd.c index 005432c2bbd..fcf5db21a03 100644 --- a/reactos/base/applications/regedit/childwnd.c +++ b/reactos/base/applications/regedit/childwnd.c @@ -65,7 +65,7 @@ static void draw_splitbar(HWND hWnd, int x) ReleaseDC(hWnd, hdc); } -static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy) +static void ResizeWnd(int cx, int cy) { HDWP hdwp = BeginDeferWindowPos(3); RECT rt, rs, rb; @@ -77,12 +77,12 @@ static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy) GetWindowRect(hStatusBar, &rs); cy = rs.bottom - rs.top; } - GetWindowRect(pChildWnd->hAddressBtnWnd, &rb); - cx = pChildWnd->nSplitPos + SPLIT_WIDTH/2; - DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left - tHeight-2, tHeight, SWP_NOZORDER|SWP_NOACTIVATE); - DeferWindowPos(hdwp, pChildWnd->hAddressBtnWnd, 0, rt.right - tHeight, rt.top, tHeight, tHeight, SWP_NOZORDER|SWP_NOACTIVATE); - DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + tHeight+2, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); - DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx, rt.top + tHeight+2, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); + GetWindowRect(g_pChildWnd->hAddressBtnWnd, &rb); + cx = g_pChildWnd->nSplitPos + SPLIT_WIDTH/2; + DeferWindowPos(hdwp, g_pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left - tHeight-2, tHeight, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, g_pChildWnd->hAddressBtnWnd, 0, rt.right - tHeight, rt.top, tHeight, tHeight, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, g_pChildWnd->hTreeWnd, 0, rt.left, rt.top + tHeight+2, g_pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, g_pChildWnd->hListWnd, 0, rt.left+cx, rt.top + tHeight+2, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); EndDeferWindowPos(hdwp); } @@ -111,7 +111,7 @@ static void finish_splitbar(HWND hWnd, int x) last_split = -1; GetClientRect(hWnd, &rt); g_pChildWnd->nSplitPos = x; - ResizeWnd(g_pChildWnd, rt.right, rt.bottom); + ResizeWnd(rt.right, rt.bottom); ReleaseCapture(); } @@ -125,7 +125,6 @@ static void finish_splitbar(HWND hWnd, int x) static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - ChildWnd* pChildWnd = g_pChildWnd; HTREEITEM hSelection; HKEY hRootKey; LPCTSTR keyPath, s; @@ -143,18 +142,18 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* TODO */ break; case ID_TREE_EXPANDBRANCH: - (void)TreeView_Expand(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd), TVE_EXPAND); + (void)TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_EXPAND); break; case ID_TREE_COLLAPSEBRANCH: - (void)TreeView_Expand(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd), TVE_COLLAPSE); + (void)TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_COLLAPSE); break; case ID_TREE_RENAME: - SetFocus(pChildWnd->hTreeWnd); - (void)TreeView_EditLabel(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd)); + SetFocus(g_pChildWnd->hTreeWnd); + (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd)); break; case ID_TREE_DELETE: - hSelection = TreeView_GetSelection(pChildWnd->hTreeWnd); - keyPath = GetItemPath(pChildWnd->hTreeWnd, hSelection, &hRootKey); + hSelection = TreeView_GetSelection(g_pChildWnd->hTreeWnd); + keyPath = GetItemPath(g_pChildWnd->hTreeWnd, hSelection, &hRootKey); if (keyPath == 0 || *keyPath == 0) { @@ -164,18 +163,18 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) DeleteNode(g_pChildWnd->hTreeWnd, 0); break; case ID_TREE_EXPORT: - ExportRegistryFile(pChildWnd->hTreeWnd); + ExportRegistryFile(g_pChildWnd->hTreeWnd); break; case ID_EDIT_FIND: FindDialog(hWnd); break; case ID_EDIT_COPYKEYNAME: - hSelection = TreeView_GetSelection(pChildWnd->hTreeWnd); - keyPath = GetItemPath(pChildWnd->hTreeWnd, hSelection, &hRootKey); + hSelection = TreeView_GetSelection(g_pChildWnd->hTreeWnd); + keyPath = GetItemPath(g_pChildWnd->hTreeWnd, hSelection, &hRootKey); CopyKeyName(hWnd, hRootKey, keyPath); break; case ID_EDIT_NEW_KEY: - CreateNewKey(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd)); + CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd)); break; case ID_EDIT_NEW_STRINGVALUE: case ID_EDIT_NEW_BINARYVALUE: @@ -183,8 +182,8 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hFrameWnd, WM_COMMAND, wParam, lParam); break; case ID_SWITCH_PANELS: - pChildWnd->nFocusPanel = !pChildWnd->nFocusPanel; - SetFocus(pChildWnd->nFocusPanel? pChildWnd->hListWnd: pChildWnd->hTreeWnd); + g_pChildWnd->nFocusPanel = !g_pChildWnd->nFocusPanel; + SetFocus(g_pChildWnd->nFocusPanel? g_pChildWnd->hListWnd: g_pChildWnd->hTreeWnd); break; default: if ((wID >= ID_TREE_SUGGESTION_MIN) && (wID <= ID_TREE_SUGGESTION_MAX)) @@ -196,7 +195,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) s += _tcslen(s) + 1; wID--; } - SelectNode(pChildWnd->hTreeWnd, s); + SelectNode(g_pChildWnd->hTreeWnd, s); break; } return FALSE; @@ -317,7 +316,6 @@ LRESULT CALLBACK AddressBarProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { BOOL Result; - ChildWnd* pChildWnd = g_pChildWnd; switch (message) { @@ -329,45 +327,45 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa /* load "My Computer" string */ LoadString(hInst, IDS_MY_COMPUTER, buffer, sizeof(buffer)/sizeof(TCHAR)); - g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd)); + g_pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd)); + if (!g_pChildWnd) return 0; - if (!pChildWnd) return 0; - _tcsncpy(pChildWnd->szPath, buffer, MAX_PATH); - pChildWnd->nSplitPos = 250; - pChildWnd->hWnd = hWnd; - pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP, + _tcsncpy(g_pChildWnd->szPath, buffer, MAX_PATH); + g_pChildWnd->nSplitPos = 250; + g_pChildWnd->hWnd = hWnd; + g_pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, (HMENU)0, hInst, 0); - pChildWnd->hAddressBtnWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Button"), _T("»"), WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_DEFPUSHBUTTON, + g_pChildWnd->hAddressBtnWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Button"), _T("»"), WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_DEFPUSHBUTTON, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, (HMENU)0, hInst, 0); - pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, (HMENU) TREE_WINDOW); - pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, pChildWnd->szPath*/); - SetFocus(pChildWnd->hTreeWnd); + g_pChildWnd->hTreeWnd = CreateTreeView(hWnd, g_pChildWnd->szPath, (HMENU) TREE_WINDOW); + g_pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, g_pChildWnd->szPath*/); + SetFocus(g_pChildWnd->hTreeWnd); /* set the address bar and button font */ - if ((pChildWnd->hAddressBarWnd) && (pChildWnd->hAddressBtnWnd)) + if ((g_pChildWnd->hAddressBarWnd) && (g_pChildWnd->hAddressBtnWnd)) { hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); - SendMessage(pChildWnd->hAddressBarWnd, + SendMessage(g_pChildWnd->hAddressBarWnd, WM_SETFONT, (WPARAM)hFont, 0); - SendMessage(pChildWnd->hAddressBtnWnd, + SendMessage(g_pChildWnd->hAddressBtnWnd, WM_SETFONT, (WPARAM)hFont, 0); } /* Subclass the AddressBar */ - oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_WNDPROC); - SetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_USERDATA, (DWORD_PTR)oldproc); - SetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_WNDPROC, (DWORD_PTR)AddressBarProc); + oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_WNDPROC); + SetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_USERDATA, (DWORD_PTR)oldproc); + SetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_WNDPROC, (DWORD_PTR)AddressBarProc); break; } case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { - PostMessage(pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0); + PostMessage(g_pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0); } else if (!_CmdWndProc(hWnd, message, wParam, lParam)) { @@ -383,7 +381,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa POINT pt; GetCursorPos(&pt); ScreenToClient(hWnd, &pt); - if (pt.x>=pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.xnSplitPos+SPLIT_WIDTH/2+1) + if (pt.x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.xnSplitPos+SPLIT_WIDTH/2+1) { SetCursor(LoadCursor(0, IDC_SIZEWE)); return TRUE; @@ -392,10 +390,10 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa goto def; case WM_DESTROY: DestroyTreeView(); - DestroyListView(pChildWnd->hListWnd); + DestroyListView(g_pChildWnd->hListWnd); DestroyMainMenu(); - HeapFree(GetProcessHeap(), 0, pChildWnd); - pChildWnd = NULL; + HeapFree(GetProcessHeap(), 0, g_pChildWnd); + g_pChildWnd = NULL; PostQuitMessage(0); break; case WM_LBUTTONDOWN: @@ -403,9 +401,9 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa RECT rt; int x = (short)LOWORD(lParam); GetClientRect(hWnd, &rt); - if (x>=pChildWnd->nSplitPos-SPLIT_WIDTH/2 && xnSplitPos+SPLIT_WIDTH/2+1) + if (x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && xnSplitPos+SPLIT_WIDTH/2+1) { - last_split = pChildWnd->nSplitPos; + last_split = g_pChildWnd->nSplitPos; draw_splitbar(hWnd, last_split); SetCapture(hWnd); } @@ -432,7 +430,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa RECT rt; draw_splitbar(hWnd, last_split); GetClientRect(hWnd, &rt); - ResizeWnd(pChildWnd, rt.right, rt.bottom); + ResizeWnd(rt.right, rt.bottom); last_split = -1; ReleaseCapture(); SetCursor(LoadCursor(0, IDC_ARROW)); @@ -476,9 +474,9 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa break; case WM_SETFOCUS: - if (pChildWnd != NULL) + if (g_pChildWnd != NULL) { - SetFocus(pChildWnd->nFocusPanel? pChildWnd->hListWnd: pChildWnd->hTreeWnd); + SetFocus(g_pChildWnd->nFocusPanel? g_pChildWnd->hListWnd: g_pChildWnd->hTreeWnd); } break; @@ -486,22 +484,22 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa break; case WM_NOTIFY: - if ((int)wParam == TREE_WINDOW) + if ((int)wParam == TREE_WINDOW && g_pChildWnd != NULL) { switch (((LPNMHDR)lParam)->code) { case TVN_ITEMEXPANDING: - return !OnTreeExpanding(pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam); + return !OnTreeExpanding(g_pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam); case TVN_SELCHANGED: { LPCTSTR keyPath, rootName; LPTSTR fullPath; HKEY hRootKey; - keyPath = GetItemPath(pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, &hRootKey); + keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, &hRootKey); if (keyPath) { - RefreshListView(pChildWnd->hListWnd, hRootKey, keyPath); + RefreshListView(g_pChildWnd->hListWnd, hRootKey, keyPath); rootName = get_root_key_name(hRootKey); fullPath = HeapAlloc(GetProcessHeap(), 0, (_tcslen(rootName) + 1 + _tcslen(keyPath) + 1) * sizeof(TCHAR)); if (fullPath) @@ -512,7 +510,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa else fullPath = _tcscpy(fullPath, rootName); SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath); - SendMessage(pChildWnd->hAddressBarWnd, WM_SETTEXT, 0, (LPARAM)fullPath); + SendMessage(g_pChildWnd->hAddressBarWnd, WM_SETTEXT, 0, (LPARAM)fullPath); HeapFree(GetProcessHeap(), 0, fullPath); /* disable hive manipulation items temporarily (enable only if necessary) */ EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_GRAYED); @@ -547,15 +545,15 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa } break; case NM_SETFOCUS: - pChildWnd->nFocusPanel = 0; + g_pChildWnd->nFocusPanel = 0; break; case TVN_BEGINLABELEDIT: { LPNMTVDISPINFO ptvdi; /* cancel label edit for rootkeys */ ptvdi = (LPNMTVDISPINFO) lParam; - if (!TreeView_GetParent(pChildWnd->hTreeWnd, ptvdi->item.hItem) || - !TreeView_GetParent(pChildWnd->hTreeWnd, TreeView_GetParent(pChildWnd->hTreeWnd, ptvdi->item.hItem))) + if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) || + !TreeView_GetParent(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem))) return TRUE; break; } @@ -571,14 +569,14 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa ptvdi = (LPNMTVDISPINFO) lParam; if (ptvdi->item.pszText) { - keyPath = GetItemPath(pChildWnd->hTreeWnd, TreeView_GetParent(pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey); + keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey); _sntprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), _T("%s\\%s"), keyPath, ptvdi->item.pszText); - keyPath = GetItemPath(pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey); + keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey); if (RegOpenKeyEx(hRootKey, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { lResult = FALSE; RegCloseKey(hKey); - (void)TreeView_EditLabel(pChildWnd->hTreeWnd, ptvdi->item.hItem); + (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, ptvdi->item.hItem); } else { @@ -594,15 +592,15 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa } else { - if ((int)wParam == LIST_WINDOW) + if ((int)wParam == LIST_WINDOW && g_pChildWnd != NULL) { switch (((LPNMHDR)lParam)->code) { case NM_SETFOCUS: - pChildWnd->nFocusPanel = 1; + g_pChildWnd->nFocusPanel = 1; break; default: - if(!ListWndNotifyProc(pChildWnd->hListWnd, wParam, lParam, &Result)) + if(!ListWndNotifyProc(g_pChildWnd->hListWnd, wParam, lParam, &Result)) { goto def; } @@ -616,27 +614,27 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa case WM_CONTEXTMENU: { POINT pt; - if((HWND)wParam == pChildWnd->hListWnd) + if((HWND)wParam == g_pChildWnd->hListWnd) { int i, cnt; BOOL IsDefault; pt.x = (short) LOWORD(lParam); pt.y = (short) HIWORD(lParam); - cnt = ListView_GetSelectedCount(pChildWnd->hListWnd); - i = ListView_GetNextItem(pChildWnd->hListWnd, -1, LVNI_FOCUSED | LVNI_SELECTED); + cnt = ListView_GetSelectedCount(g_pChildWnd->hListWnd); + i = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED | LVNI_SELECTED); if (pt.x == -1 && pt.y == -1) { RECT rc; if (i != -1) { rc.left = LVIR_BOUNDS; - SendMessage(pChildWnd->hListWnd, LVM_GETITEMRECT, i, (LPARAM) &rc); + SendMessage(g_pChildWnd->hListWnd, LVM_GETITEMRECT, i, (LPARAM) &rc); pt.x = rc.left + 8; pt.y = rc.top + 8; } else pt.x = pt.y = 0; - ClientToScreen(pChildWnd->hListWnd, &pt); + ClientToScreen(g_pChildWnd->hListWnd, &pt); } if(i == -1) { @@ -646,7 +644,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa { HMENU mnu = GetSubMenu(hPopupMenus, PM_MODIFYVALUE); SetMenuDefaultItem(mnu, ID_EDIT_MODIFY, MF_BYCOMMAND); - IsDefault = IsDefaultValue(pChildWnd->hListWnd, i); + IsDefault = IsDefaultValue(g_pChildWnd->hListWnd, i); if(cnt == 1) EnableMenuItem(mnu, ID_EDIT_RENAME, MF_BYCOMMAND | (IsDefault ? MF_DISABLED | MF_GRAYED : MF_ENABLED)); else @@ -657,7 +655,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa TrackPopupMenu(mnu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL); } } - else if ((HWND)wParam == pChildWnd->hTreeWnd) + else if ((HWND)wParam == g_pChildWnd->hTreeWnd) { TVHITTESTINFO hti; HMENU hContextMenu; @@ -677,13 +675,13 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa if (pt.x == -1 && pt.y == -1) { RECT rc; - hti.hItem = TreeView_GetSelection(pChildWnd->hTreeWnd); + hti.hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd); if (hti.hItem != NULL) { - TreeView_GetItemRect(pChildWnd->hTreeWnd, hti.hItem, &rc, TRUE); + TreeView_GetItemRect(g_pChildWnd->hTreeWnd, hti.hItem, &rc, TRUE); pt.x = rc.left + 8; pt.y = rc.top + 8; - ClientToScreen(pChildWnd->hTreeWnd, &pt); + ClientToScreen(g_pChildWnd->hTreeWnd, &pt); hti.flags = TVHT_ONITEM; } else @@ -693,19 +691,19 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa { hti.pt.x = pt.x; hti.pt.y = pt.y; - ScreenToClient(pChildWnd->hTreeWnd, &hti.pt); - (void)TreeView_HitTest(pChildWnd->hTreeWnd, &hti); + ScreenToClient(g_pChildWnd->hTreeWnd, &hti.pt); + (void)TreeView_HitTest(g_pChildWnd->hTreeWnd, &hti); } if (hti.flags & TVHT_ONITEM) { hContextMenu = GetSubMenu(hPopupMenus, PM_TREECONTEXT); - (void)TreeView_SelectItem(pChildWnd->hTreeWnd, hti.hItem); + (void)TreeView_SelectItem(g_pChildWnd->hTreeWnd, hti.hItem); memset(&item, 0, sizeof(item)); item.mask = TVIF_STATE | TVIF_CHILDREN; item.hItem = hti.hItem; - (void)TreeView_GetItem(pChildWnd->hTreeWnd, &item); + (void)TreeView_GetItem(g_pChildWnd->hTreeWnd, &item); /* Set the Expand/Collapse menu item appropriately */ LoadString(hInst, (item.state & TVIS_EXPANDED) ? IDS_COLLAPSE : IDS_EXPAND, buffer, sizeof(buffer) / sizeof(buffer[0])); @@ -734,7 +732,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa } /* Come up with suggestions */ - keyPath = GetItemPath(pChildWnd->hTreeWnd, NULL, &hRootKey); + keyPath = GetItemPath(g_pChildWnd->hTreeWnd, NULL, &hRootKey); SuggestKeys(hRootKey, keyPath, Suggestions, sizeof(Suggestions) / sizeof(Suggestions[0])); if (Suggestions[0]) { @@ -758,16 +756,16 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa s += _tcslen(s) + 1; } } - TrackPopupMenu(hContextMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, pChildWnd->hWnd, NULL); + TrackPopupMenu(hContextMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, g_pChildWnd->hWnd, NULL); } } break; } case WM_SIZE: - if (wParam != SIZE_MINIMIZED && pChildWnd != NULL) + if (wParam != SIZE_MINIMIZED && g_pChildWnd != NULL) { - ResizeWnd(pChildWnd, LOWORD(lParam), HIWORD(lParam)); + ResizeWnd(LOWORD(lParam), HIWORD(lParam)); } /* fall through */ default: diff --git a/reactos/dll/cpl/input/settings.c b/reactos/dll/cpl/input/settings.c index 393359dd7a2..5f1ca81e066 100644 --- a/reactos/dll/cpl/input/settings.c +++ b/reactos/dll/cpl/input/settings.c @@ -14,7 +14,6 @@ #include "input.h" static HWND MainDlgWnd; -static HIMAGELIST hImgList; // for SaveInputLang() static INT OldLayoutNum; @@ -299,7 +298,7 @@ AddListColumn(HWND hWnd) } static VOID -InitLangList(HWND hWnd) +InitLangList(HWND hWnd, HIMAGELIST hImgList) { HKEY hKey, hSubKey; TCHAR szBuf[MAX_PATH], szPreload[CCH_LAYOUT_ID + 1], szSub[CCH_LAYOUT_ID + 1]; @@ -370,11 +369,19 @@ InitLangList(HWND hWnd) VOID UpdateLayoutsList(VOID) { - (VOID) ImageList_Destroy(hImgList); + HIMAGELIST hImgList; + + /* Clear the list */ (VOID) ListView_DeleteAllItems(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST)); + + /* Crate new list */ hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 0, 1); - InitLangList(MainDlgWnd); - (VOID) ListView_SetImageList(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), hImgList, LVSIL_SMALL); + InitLangList(MainDlgWnd, hImgList); + hImgList = ListView_SetImageList(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), hImgList, LVSIL_SMALL); + + /* Destroy old image list */ + if(hImgList) + (VOID) ImageList_Destroy(hImgList); } typedef struct _REG_KB_ENTRY_ @@ -728,12 +735,14 @@ SettingPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) { case WM_INITDIALOG: { + HIMAGELIST hImgList; + MainDlgWnd = hwndDlg; AddListColumn(hwndDlg); (VOID) ListView_SetExtendedListViewStyle(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), LVS_EX_FULLROWSELECT); hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 0, 1); - InitLangList(hwndDlg); + InitLangList(hwndDlg, hImgList); (VOID) ListView_SetImageList(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), hImgList, LVSIL_SMALL); } break; @@ -781,7 +790,6 @@ SettingPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) } break; case WM_DESTROY: - (VOID) ImageList_Destroy(hImgList); break; } From 8fb7057c46b77f3accc9ff8845acb4e1c6299d9a Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 14:16:01 +0000 Subject: [PATCH 42/90] Set last error to ERROR_PROC_NOT_FOUND in case of NULL module in GetProcAddress Check for error when freeing datafile Fixes 2 winetests svn path=/trunk/; revision=51104 --- reactos/dll/win32/kernel32/misc/ldr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/ldr.c b/reactos/dll/win32/kernel32/misc/ldr.c index 6a954ae802c..decc300fbab 100644 --- a/reactos/dll/win32/kernel32/misc/ldr.c +++ b/reactos/dll/win32/kernel32/misc/ldr.c @@ -310,6 +310,12 @@ GetProcAddress( HMODULE hModule, LPCSTR lpProcName ) FARPROC fnExp = NULL; NTSTATUS Status; + if (!hModule) + { + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } + if (HIWORD(lpProcName) != 0) { RtlInitAnsiString (&ProcedureName, @@ -354,8 +360,7 @@ BOOL WINAPI FreeLibrary(HINSTANCE hLibModule) { /* this is a LOAD_LIBRARY_AS_DATAFILE module */ char *ptr = (char *)hLibModule - 1; - UnmapViewOfFile(ptr); - return TRUE; + return UnmapViewOfFile(ptr); } Status = LdrUnloadDll(hLibModule); From 32b6884390a742de1936807906309cd68b8367c8 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 14:21:16 +0000 Subject: [PATCH 43/90] Don't assume WM_DESTROY is last message - listview sends notification after it. Confirmed in Windows 7. See issue #6026 for more details. svn path=/trunk/; revision=51105 --- reactos/dll/win32/devmgr/hwpage.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reactos/dll/win32/devmgr/hwpage.c b/reactos/dll/win32/devmgr/hwpage.c index 0b26bd67866..57b52d22e0f 100644 --- a/reactos/dll/win32/devmgr/hwpage.c +++ b/reactos/dll/win32/devmgr/hwpage.c @@ -964,6 +964,9 @@ HardwareDlgProc(IN HWND hwndDlg, case WM_DESTROY: { + /* zero hpd pointer in window data, because it can be used later (WM_DESTROY has not to be last message) */ + SetWindowLongPtr(hwndDlg, DWL_USER, (DWORD_PTR)NULL); + /* free devices list */ FreeDevicesList(hpd); From 6a7c60945f633baf223457dcc42cfbc35de21486 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 14:32:46 +0000 Subject: [PATCH 44/90] Set last error to ERROR_INVALID_PARAMETER in NtGdiGetRandomRgn if invalid hdc is given Fixes gdi32:GetClipRgn apitest svn path=/trunk/; revision=51106 --- reactos/subsystems/win32/win32k/objects/dcobjs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/dcobjs.c b/reactos/subsystems/win32/win32k/objects/dcobjs.c index 7e6870be76f..6a7cf20661b 100644 --- a/reactos/subsystems/win32/win32k/objects/dcobjs.c +++ b/reactos/subsystems/win32/win32k/objects/dcobjs.c @@ -367,7 +367,7 @@ NtGdiSelectBitmap( REGION_FreeRgnByHandle(hVisRgn); } - /* Return the old bitmp handle */ + /* Return the old bitmap handle */ return hbmpOld; } @@ -522,7 +522,7 @@ NtGdiGetRandomRgn( pdc = DC_LockDc(hdc); if (!pdc) { - EngSetLastError(ERROR_INVALID_HANDLE); + EngSetLastError(ERROR_INVALID_PARAMETER); return -1; } From 96de2d1363c1c8267867090dfb91a742d3e925e8 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 14:36:32 +0000 Subject: [PATCH 45/90] Improve GetClipRgn and SetSysColors apitests svn path=/trunk/; revision=51107 --- rostests/apitests/gdi32/GetClipRgn.c | 11 +++++---- rostests/apitests/gdi32/SetSysColors.c | 32 +++++++++++++++++++------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/rostests/apitests/gdi32/GetClipRgn.c b/rostests/apitests/gdi32/GetClipRgn.c index 7ca818773fa..35221489f78 100644 --- a/rostests/apitests/gdi32/GetClipRgn.c +++ b/rostests/apitests/gdi32/GetClipRgn.c @@ -14,6 +14,7 @@ void Test_GetClipRgn() HWND hWnd; HDC hDC; HRGN hrgn;//, hrgn2; + int ret; /* Create a window */ hWnd = CreateWindowW(L"BUTTON", L"TestWindow", WS_OVERLAPPEDWINDOW | WS_VISIBLE, @@ -25,13 +26,15 @@ void Test_GetClipRgn() /* Test invalid DC */ SetLastError(ERROR_SUCCESS); - ok(GetClipRgn((HDC)0x12345, hrgn) == -1, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + ret = GetClipRgn((HDC)0x12345, hrgn); + ok(ret == -1, "Expected -1, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Test invalid hrgn */ SetLastError(ERROR_SUCCESS); - ok(GetClipRgn(hDC, (HRGN)0x12345) == 0, "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + ret = GetClipRgn(hDC, (HRGN)0x12345); + ok(ret == 0, "Expected 0, got %d\n", ret); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); ReleaseDC(hWnd, hDC); DestroyWindow(hWnd); diff --git a/rostests/apitests/gdi32/SetSysColors.c b/rostests/apitests/gdi32/SetSysColors.c index 1c75fbf8c82..26a71854414 100644 --- a/rostests/apitests/gdi32/SetSysColors.c +++ b/rostests/apitests/gdi32/SetSysColors.c @@ -10,16 +10,15 @@ #include #define TEST(x) ok(x, #x"\n") -#define RTEST(x) ok(x, #x"\n") #define NUM_SYSCOLORS 31 void Test_SetSysColors() { INT i; - INT nElements[NUM_SYSCOLORS]; + INT nElements[NUM_SYSCOLORS+1]; COLORREF crOldColors[NUM_SYSCOLORS]; - COLORREF crColors[3] = {RGB(212, 208, 200),2,3}; + COLORREF crColors[NUM_SYSCOLORS+1]; /* First save the Old colors */ for (i = 0; i < NUM_SYSCOLORS; i++) @@ -27,13 +26,30 @@ void Test_SetSysColors() nElements[i] = i; crOldColors[i] = GetSysColor(i); } - - TEST((UINT)SetSysColors(0, nElements, crColors) == 1); - RTEST((UINT)SetSysColors(1, nElements, crColors) == 1); - RTEST((UINT)SetSysColors(2, nElements, crColors) == 1); + + for (i = 0; i < NUM_SYSCOLORS+1; i++) + crColors[i] = RGB(i, 255-i, i*3); + nElements[NUM_SYSCOLORS] = nElements[0]; + + SetLastError(0xdeadbeef); + ok(SetSysColors(-1, nElements, crColors) == FALSE, "Expected FALSE, got TRUE\n"); + ok(GetLastError() == ERROR_NOACCESS, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + ok(SetSysColors(0, nElements, crColors) == TRUE, "Expected TRUE, got FALSE\n"); + ok(SetSysColors(0, NULL, crColors) == TRUE, "Expected TRUE, got FALSE\n"); + ok(SetSysColors(0, nElements, NULL) == TRUE, "Expected TRUE, got FALSE\n"); + ok(SetSysColors(1, NULL, crColors) == FALSE, "Expected FALSE, got TRUE\n"); + ok(GetLastError() == ERROR_NOACCESS, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + ok(SetSysColors(1, nElements, NULL) == FALSE, "Expected FALSE, got TRUE\n"); + ok(GetLastError() == ERROR_NOACCESS, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + ok(SetSysColors(1, nElements, crColors) == TRUE, "Expected TRUE, got FALSE\n"); + ok(SetSysColors(NUM_SYSCOLORS, nElements, crColors) == TRUE, "Expected TRUE, got FALSE\n"); + for (i = 0; i < NUM_SYSCOLORS; i++) + ok(GetSysColor(nElements[i]) == crColors[i], "Expected %06lx, got %06lx\n", crColors[i], GetSysColor(nElements[i])); /* try more than NUM_SYSCOLORS */ - RTEST((UINT)SetSysColors(55, nElements, crColors) == 1); + ok(SetSysColors(NUM_SYSCOLORS+1, nElements, crColors) == TRUE, "Expected TRUE, got FALSE\n"); + nElements[NUM_SYSCOLORS] = 10000; + ok(SetSysColors(NUM_SYSCOLORS+1, nElements, crColors) == TRUE, "Expected TRUE, got FALSE\n"); /* restore old SysColors */ SetSysColors(NUM_SYSCOLORS, nElements, crOldColors); From ec3c8d24410410c4bcd663175b1243ed71b61615 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 14:43:56 +0000 Subject: [PATCH 46/90] Fix ProbeForRead. It wasn't ever checking if memory can be accessed. Thanks to big-endian it wasn't breaking MmUserProbeAddress as well. Code is now nearly the same as in ProbeForWrite. It shouldn't break anything. If it does, it's not bug in this code. :) svn path=/trunk/; revision=51108 --- reactos/ntoskrnl/ex/exintrin.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/reactos/ntoskrnl/ex/exintrin.c b/reactos/ntoskrnl/ex/exintrin.c index 0d98379b99e..3e9d5c3f6b5 100644 --- a/reactos/ntoskrnl/ex/exintrin.c +++ b/reactos/ntoskrnl/ex/exintrin.c @@ -103,6 +103,8 @@ ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment) { + ULONG_PTR Last, Current = (ULONG_PTR)Address; + CHAR Temp; PAGED_CODE(); /* Only probe if we have a valid length */ @@ -115,18 +117,31 @@ ProbeForRead(IN CONST VOID *Address, (Alignment == 8) || (Alignment == 16)); - /* Check for correct alignment */ - if (((ULONG_PTR)Address & (Alignment - 1)) != 0) + /* Check the alignment */ + if ((Current & (Alignment - 1)) != 0) { /* Incorrect alignment */ ExRaiseDatatypeMisalignment(); } - else if (((ULONG_PTR)Address + Length) < (ULONG_PTR)Address || - ((ULONG_PTR)Address + Length) > (ULONG_PTR)MmUserProbeAddress) + + /* Get the end address */ + Last = Current + Length - 1; + if ((Last < Current) || (Last >= (ULONG_PTR)MmUserProbeAddress)) + { + /* Raise an access violation */ + ExRaiseAccessViolation(); + } + + /* Round down to the last page */ + Last = PAGE_ROUND_DOWN(Last) + PAGE_SIZE; + do { /* Attempt a read */ - *(volatile CHAR* const)MmUserProbeAddress = 0; - } + Temp = *(volatile CHAR*)Current; + + /* Go to the next address */ + Current = PAGE_ROUND_DOWN(Current) + PAGE_SIZE; + } while (Current != Last); } } From 347b8aee6f711f900060b78f1943e0978cd16716 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 14:47:06 +0000 Subject: [PATCH 47/90] Make sure rectangle is not inverted in Rectangle function Fixes gdi32:Rectangle apitest svn path=/trunk/; revision=51109 --- reactos/subsystems/win32/win32k/objects/fillshap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/fillshap.c b/reactos/subsystems/win32/win32k/objects/fillshap.c index ae071d2cddf..0fb1695c1b6 100644 --- a/reactos/subsystems/win32/win32k/objects/fillshap.c +++ b/reactos/subsystems/win32/win32k/objects/fillshap.c @@ -545,10 +545,11 @@ IntRectangle(PDC dc, return PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect ); } - DestRect.left = LeftRect; - DestRect.right = RightRect; - DestRect.top = TopRect; - DestRect.bottom = BottomRect; + /* Make sure rectangle is not inverted */ + DestRect.left = min(LeftRect, RightRect); + DestRect.right = max(LeftRect, RightRect); + DestRect.top = min(TopRect, BottomRect); + DestRect.bottom = max(TopRect, BottomRect); IntLPtoDP(dc, (LPPOINT)&DestRect, 2); From f561f03d31ee056f2cc102bb5d16800b10cebcb0 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 14:52:08 +0000 Subject: [PATCH 48/90] Fix gdi32:SetSysColors apitest svn path=/trunk/; revision=51110 --- .../subsystems/win32/win32k/include/intgdi.h | 4 +- .../subsystems/win32/win32k/ntuser/ntstubs.c | 50 ++++++++++--------- .../win32/win32k/objects/stockobj.c | 5 +- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/intgdi.h b/reactos/subsystems/win32/win32k/include/intgdi.h index 5e7ca97d68f..c88545cfa4f 100644 --- a/reactos/subsystems/win32/win32k/include/intgdi.h +++ b/reactos/subsystems/win32/win32k/include/intgdi.h @@ -156,8 +156,8 @@ IntGdiCombineTransform(LPXFORM XFormResult, /* Stock objects */ -BOOL FASTCALL -IntSetSysColors(UINT nColors, INT *Elements, COLORREF *Colors); +VOID FASTCALL +IntSetSysColors(UINT nColors, CONST INT *Elements, CONST COLORREF *Colors); HGDIOBJ FASTCALL IntGetSysColorBrush(INT Object); diff --git a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c index 1f7615debf2..7cdc720cd0a 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c @@ -538,36 +538,40 @@ NtUserSetSysColors( IN CONST COLORREF *lpaRgbValues, FLONG Flags) { - DWORD Ret = FALSE; - NTSTATUS Status = STATUS_SUCCESS; - UserEnterExclusive(); - _SEH2_TRY - { - ProbeForRead(lpaElements, + DWORD Ret = TRUE; + NTSTATUS Status = STATUS_SUCCESS; + + if (cElements == 0) + return TRUE; + + UserEnterExclusive(); + _SEH2_TRY + { + ProbeForRead(lpaElements, sizeof(INT), 1); - ProbeForRead(lpaRgbValues, - sizeof(INT), + ProbeForRead(lpaRgbValues, + sizeof(COLORREF), 1); // Developers: We are thread locked and calling gdi. - Ret = IntSetSysColors(cElements, (INT*)lpaElements, (COLORREF*)lpaRgbValues); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { + IntSetSysColors(cElements, lpaElements, lpaRgbValues); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - if (!NT_SUCCESS(Status)) - { + } + _SEH2_END; + if (!NT_SUCCESS(Status)) + { SetLastNtError(Status); Ret = FALSE; - } - if (Ret) - { - UserSendNotifyMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); - } - UserLeave(); - return Ret; + } + if (Ret) + { + UserSendNotifyMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); + } + UserLeave(); + return Ret; } DWORD diff --git a/reactos/subsystems/win32/win32k/objects/stockobj.c b/reactos/subsystems/win32/win32k/objects/stockobj.c index 02b07dfbf94..ca8a5e744e2 100644 --- a/reactos/subsystems/win32/win32k/objects/stockobj.c +++ b/reactos/subsystems/win32/win32k/objects/stockobj.c @@ -216,8 +216,8 @@ NtGdiGetStockObject(INT Object) return ((Object < 0) || (NB_STOCK_OBJECTS <= Object)) ? NULL : StockObjects[Object]; } -BOOL FASTCALL -IntSetSysColors(UINT nColors, INT *Elements, COLORREF *Colors) +VOID FASTCALL +IntSetSysColors(UINT nColors, CONST INT *Elements, CONST COLORREF *Colors) { UINT i; @@ -234,7 +234,6 @@ IntSetSysColors(UINT nColors, INT *Elements, COLORREF *Colors) Elements++; Colors++; } - return nColors > 0; } HGDIOBJ FASTCALL From 08632f712884ab7609811ef7567b892b9fb72d44 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 17:58:08 +0000 Subject: [PATCH 49/90] [GDI32] GetTextExtentExPointW doesn't fail if nMaxExtent is negative (only ANSI version does) Fixes gdi32:GetTextExtentExPoint apitest svn path=/trunk/; revision=51111 --- reactos/dll/win32/gdi32/objects/text.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/text.c b/reactos/dll/win32/gdi32/objects/text.c index 75b79c30b8a..5de6edcb597 100644 --- a/reactos/dll/win32/gdi32/objects/text.c +++ b/reactos/dll/win32/gdi32/objects/text.c @@ -194,11 +194,9 @@ GetTextExtentExPointW( ) { + /* Windows doesn't check nMaxExtent validity in unicode version */ if(nMaxExtent < -1) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + DPRINT("nMaxExtent is invalid: %d\n", nMaxExtent); return NtGdiGetTextExtentExW ( hdc, (LPWSTR)lpszStr, cchString, nMaxExtent, (PULONG)lpnFit, (PULONG)alpDx, lpSize, 0 ); From 46afc9aa8cc97042a8945aa0b278d1da3dab0745 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Mon, 21 Mar 2011 18:30:17 +0000 Subject: [PATCH 50/90] Fix for r51111. Fixes build... svn path=/trunk/; revision=51112 --- reactos/dll/win32/gdi32/objects/text.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/dll/win32/gdi32/objects/text.c b/reactos/dll/win32/gdi32/objects/text.c index 5de6edcb597..e434532fc43 100644 --- a/reactos/dll/win32/gdi32/objects/text.c +++ b/reactos/dll/win32/gdi32/objects/text.c @@ -1,5 +1,7 @@ #include "precomp.h" +#define NDEBUG +#include /* * @implemented From 1df2f8464a0fa613faaef6903cc7ff36c9d23126 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 21 Mar 2011 22:58:47 +0000 Subject: [PATCH 51/90] [NTDLL/LDR] - Implement misc utility functions needed for monstrous LdrpInitializeProcess(). Currently unused. svn path=/trunk/; revision=51113 --- reactos/dll/ntdll/include/ntdllp.h | 37 +++++++++++++- reactos/dll/ntdll/ldr/ldrutils.c | 81 ++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index fcb04a98a6e..097f8522d1c 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -8,7 +8,7 @@ /* INCLUDES ******************************************************************/ -extern BOOLEAN ShowSnaps; +#define LDR_HASH_TABLE_ENTRIES 32 typedef struct _LDRP_TLS_DATA { @@ -24,6 +24,8 @@ typedef BOOL /* Global data */ extern RTL_CRITICAL_SECTION LdrpLoaderLock; extern BOOLEAN LdrpInLdrInit; +extern LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]; +extern BOOLEAN ShowSnaps; /* ldrinit.c */ NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL); @@ -34,6 +36,7 @@ VOID NTAPI LdrpFreeTls(VOID); VOID NTAPI LdrpTlsCallback(PVOID BaseAddress, ULONG Reason); BOOLEAN NTAPI LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint, PVOID BaseAddress, ULONG Reason, PVOID Context); NTSTATUS NTAPI LdrpInitializeProcess(PCONTEXT Context, PVOID SystemArgument1); +VOID NTAPI LdrpInitFailure(NTSTATUS Status); /* ldrpe.c */ @@ -48,6 +51,11 @@ LdrpSnapThunk(IN PVOID ExportBase, IN BOOLEAN Static, IN LPSTR DllName); +NTSTATUS NTAPI +LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry); + + /* ldrutils.c */ NTSTATUS NTAPI LdrpGetProcedureAddress(IN PVOID BaseAddress, @@ -55,6 +63,13 @@ LdrpGetProcedureAddress(IN PVOID BaseAddress, IN ULONG Ordinal, OUT PVOID *ProcedureAddress, IN BOOLEAN ExecuteInit); + +PLDR_DATA_TABLE_ENTRY NTAPI +LdrpAllocateDataTableEntry(IN PVOID BaseAddress); + +VOID NTAPI +LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry); + NTSTATUS NTAPI LdrpLoadDll(IN BOOLEAN Redirected, IN PWSTR DllPath OPTIONAL, @@ -66,6 +81,26 @@ LdrpLoadDll(IN BOOLEAN Redirected, ULONG NTAPI LdrpClearLoadInProgress(); +BOOLEAN NTAPI +LdrpCheckForLoadedDll(IN PWSTR DllPath, + IN PUNICODE_STRING DllName, + IN BOOLEAN Flag, + IN BOOLEAN RedirectedDll, + OUT PLDR_DATA_TABLE_ENTRY *LdrEntry); + +NTSTATUS NTAPI +LdrpMapDll(IN PWSTR SearchPath OPTIONAL, + IN PWSTR DllPath2, + IN PWSTR DllName OPTIONAL, + IN PULONG DllCharacteristics, + IN BOOLEAN Static, + IN BOOLEAN Redirect, + OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry); + +PVOID NTAPI +LdrpFetchAddressOfEntryPoint(PVOID ImageBase); + + /* FIXME: Cleanup this mess */ typedef NTSTATUS (NTAPI *PEPFUNC)(PPEB); NTSTATUS LdrMapSections(HANDLE ProcessHandle, diff --git a/reactos/dll/ntdll/ldr/ldrutils.c b/reactos/dll/ntdll/ldr/ldrutils.c index 87ae93b2be6..38eb702f395 100644 --- a/reactos/dll/ntdll/ldr/ldrutils.c +++ b/reactos/dll/ntdll/ldr/ldrutils.c @@ -17,6 +17,8 @@ PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache; +#define LDR_GET_HASH_ENTRY(x) (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1)) + /* FUNCTIONS *****************************************************************/ BOOLEAN @@ -82,6 +84,85 @@ LdrpTlsCallback(PVOID BaseAddress, ULONG Reason) _SEH2_END; } +PVOID +NTAPI +LdrpFetchAddressOfEntryPoint(PVOID ImageBase) +{ + PIMAGE_NT_HEADERS NtHeaders; + ULONG_PTR EntryPoint; + + /* Get entry point offset from NT headers */ + NtHeaders = RtlImageNtHeader(ImageBase); + EntryPoint = NtHeaders->OptionalHeader.AddressOfEntryPoint; + + /* If it's 0 - return so */ + if (!EntryPoint) return NULL; + + /* Add image base */ + EntryPoint += (ULONG_PTR)ImageBase; + + /* Return calculated pointer */ + return (PVOID)EntryPoint; +} + +NTSTATUS +NTAPI +LdrpMapDll(IN PWSTR SearchPath OPTIONAL, + IN PWSTR DllPath2, + IN PWSTR DllName OPTIONAL, + IN PULONG DllCharacteristics, + IN BOOLEAN Static, + IN BOOLEAN Redirect, + OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry) +{ + UNIMPLEMENTED; + return STATUS_SUCCESS; +} + +PLDR_DATA_TABLE_ENTRY +NTAPI +LdrpAllocateDataTableEntry(IN PVOID BaseAddress) +{ + PLDR_DATA_TABLE_ENTRY LdrEntry = NULL; + PIMAGE_NT_HEADERS NtHeader = RtlImageNtHeader(BaseAddress); + + /* Make sure the header is valid */ + if (NtHeader) + { + /* Allocate an entry */ + LdrEntry = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(LDR_DATA_TABLE_ENTRY)); + + /* Make sure we got one */ + if (LdrEntry) + { + /* Set it up */ + LdrEntry->DllBase = BaseAddress; + LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage; + LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp; + } + } + + /* Return the entry */ + return LdrEntry; +} + +VOID +NTAPI +LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) +{ + PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr; + ULONG i; + + /* Get the Hash entry */ + i = LDR_GET_HASH_ENTRY(LdrEntry->BaseDllName.Buffer[0]); + + InsertTailList(&LdrpHashTable[i], &LdrEntry->HashLinks); + InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks); + InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderModuleList); +} + BOOLEAN NTAPI LdrpCheckForLoadedDllHandle(IN PVOID Base, From eb3ddf59b3adebbac9bed1fb5df3a87e93c412c2 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Tue, 22 Mar 2011 06:53:56 +0000 Subject: [PATCH 52/90] [NTDLL] Fixed build svn path=/trunk/; revision=51114 --- reactos/dll/ntdll/ldr/ldrutils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/dll/ntdll/ldr/ldrutils.c b/reactos/dll/ntdll/ldr/ldrutils.c index 38eb702f395..b45ca1a21ae 100644 --- a/reactos/dll/ntdll/ldr/ldrutils.c +++ b/reactos/dll/ntdll/ldr/ldrutils.c @@ -16,6 +16,7 @@ /* GLOBALS *******************************************************************/ PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache; +LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]; #define LDR_GET_HASH_ENTRY(x) (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1)) From 8cf95d13197459321bbd67f198592f4702b606f7 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Tue, 22 Mar 2011 09:19:26 +0000 Subject: [PATCH 53/90] [ntoskrnl] - Implement calling OkayToCloseProcedure callouts to win32k for desktop and window station objects - Fix a bug that caused ObpCloseHandle to return success even when OkayToCloseProcedure failed [win32k] - Rewrite SetProcessWindowStation to actually set the current window station and close the previous one - Implement OkayToCloseProcedure callouts from the kernel to prevent closing the current desktop or window station svn path=/trunk/; revision=51115 --- reactos/ntoskrnl/ex/win32k.c | 38 +++++++ reactos/ntoskrnl/ob/obhandle.c | 1 - reactos/ntoskrnl/ps/win32.c | 4 + .../subsystems/win32/win32k/include/desktop.h | 3 + .../subsystems/win32/win32k/include/win32.h | 1 + .../subsystems/win32/win32k/include/winsta.h | 6 + .../subsystems/win32/win32k/main/dllmain.c | 21 ++-- .../subsystems/win32/win32k/ntuser/desktop.c | 23 ++++ .../subsystems/win32/win32k/ntuser/winsta.c | 105 ++++++++++++------ 9 files changed, 154 insertions(+), 48 deletions(-) diff --git a/reactos/ntoskrnl/ex/win32k.c b/reactos/ntoskrnl/ex/win32k.c index ef914065e86..9cd929996c9 100644 --- a/reactos/ntoskrnl/ex/win32k.c +++ b/reactos/ntoskrnl/ex/win32k.c @@ -37,10 +37,46 @@ GENERIC_MAPPING ExpDesktopMapping = PKWIN32_PARSEMETHOD_CALLOUT ExpWindowStationObjectParse = NULL; PKWIN32_DELETEMETHOD_CALLOUT ExpWindowStationObjectDelete = NULL; +PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpWindowStationObjectOkToClose = NULL; +PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpDesktopObjectOkToClose = NULL; PKWIN32_DELETEMETHOD_CALLOUT ExpDesktopObjectDelete = NULL; /* FUNCTIONS ****************************************************************/ +NTSTATUS +NTAPI +ExpDesktopOkToClose( IN PEPROCESS Process OPTIONAL, + IN PVOID Object, + IN HANDLE Handle, + IN KPROCESSOR_MODE AccessMode) +{ + WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters; + + Parameters.Process = Process; + Parameters.Object = Object; + Parameters.Handle = Handle; + Parameters.PreviousMode = AccessMode; + + return ExpDesktopObjectOkToClose(&Parameters); +} + +NTSTATUS +NTAPI +ExpWindowStationOkToClose( IN PEPROCESS Process OPTIONAL, + IN PVOID Object, + IN HANDLE Handle, + IN KPROCESSOR_MODE AccessMode) +{ + WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters; + + Parameters.Process = Process; + Parameters.Object = Object; + Parameters.Handle = Handle; + Parameters.PreviousMode = AccessMode; + + return ExpWindowStationObjectOkToClose(&Parameters); +} + VOID NTAPI ExpWinStaObjectDelete(PVOID DeletedObject) @@ -114,6 +150,7 @@ ExpWin32kInit(VOID) ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DeleteProcedure = ExpWinStaObjectDelete; ObjectTypeInitializer.ParseProcedure = ExpWinStaObjectParse; + ObjectTypeInitializer.OkayToCloseProcedure = ExpWindowStationOkToClose; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, @@ -124,6 +161,7 @@ ExpWin32kInit(VOID) ObjectTypeInitializer.GenericMapping = ExpDesktopMapping; ObjectTypeInitializer.DeleteProcedure = ExpDesktopDelete; ObjectTypeInitializer.ParseProcedure = NULL; + ObjectTypeInitializer.OkayToCloseProcedure = ExpDesktopOkToClose; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index 20d15651d4c..e19d020aa30 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -1752,7 +1752,6 @@ ObpCloseHandle(IN HANDLE Handle, /* Detach and return success */ if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); - Status = STATUS_SUCCESS; } else { diff --git a/reactos/ntoskrnl/ps/win32.c b/reactos/ntoskrnl/ps/win32.c index 3a5c2c5b900..19dd4e9c43d 100644 --- a/reactos/ntoskrnl/ps/win32.c +++ b/reactos/ntoskrnl/ps/win32.c @@ -20,6 +20,8 @@ PKWIN32_THREAD_CALLOUT PspW32ThreadCallout = NULL; PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch = NULL; extern PKWIN32_PARSEMETHOD_CALLOUT ExpWindowStationObjectParse; extern PKWIN32_DELETEMETHOD_CALLOUT ExpWindowStationObjectDelete; +extern PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpWindowStationObjectOkToClose; +extern PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpDesktopObjectOkToClose; extern PKWIN32_DELETEMETHOD_CALLOUT ExpDesktopObjectDelete; extern PKWIN32_POWEREVENT_CALLOUT PopEventCallout; @@ -116,6 +118,8 @@ PsEstablishWin32Callouts(IN PWIN32_CALLOUTS_FPNS CalloutData) PspW32ThreadCallout = CalloutData->ThreadCallout; ExpWindowStationObjectParse = CalloutData->WindowStationParseProcedure; ExpWindowStationObjectDelete = CalloutData->WindowStationDeleteProcedure; + ExpWindowStationObjectOkToClose = CalloutData->WindowStationOkToCloseProcedure; + ExpDesktopObjectOkToClose = CalloutData->DesktopOkToCloseProcedure; ExpDesktopObjectDelete = CalloutData->DesktopDeleteProcedure; PopEventCallout = CalloutData->PowerEventCallout; KeGdiFlushUserBatch = CalloutData->BatchFlushRoutine; diff --git a/reactos/subsystems/win32/win32k/include/desktop.h b/reactos/subsystems/win32/win32k/include/desktop.h index 388a0f4c23c..82607df23dc 100644 --- a/reactos/subsystems/win32/win32k/include/desktop.h +++ b/reactos/subsystems/win32/win32k/include/desktop.h @@ -69,6 +69,9 @@ IntDesktopObjectParse(IN PVOID ParseObject, VOID APIENTRY IntDesktopObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters); +NTSTATUS NTAPI +IntDesktopOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters); + LRESULT CALLBACK IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); diff --git a/reactos/subsystems/win32/win32k/include/win32.h b/reactos/subsystems/win32/win32k/include/win32.h index 521ef7a407c..2e43ec1517f 100644 --- a/reactos/subsystems/win32/win32k/include/win32.h +++ b/reactos/subsystems/win32/win32k/include/win32.h @@ -166,6 +166,7 @@ typedef struct _PROCESSINFO PCLS pclsPrivateList; PCLS pclsPublicList; INT cThreads; + HDESK hdeskStartup; DWORD dwhmodLibLoadedMask; HANDLE ahmodLibLoaded[CLIBS]; struct _WINSTATION_OBJECT *prpwinsta; diff --git a/reactos/subsystems/win32/win32k/include/winsta.h b/reactos/subsystems/win32/win32k/include/winsta.h index c40d14bf419..01a5fb77543 100644 --- a/reactos/subsystems/win32/win32k/include/winsta.h +++ b/reactos/subsystems/win32/win32k/include/winsta.h @@ -82,6 +82,9 @@ NTSTATUS APIENTRY IntWinStaObjectParse(PWIN32_PARSEMETHOD_PARAMETERS Parameters); +NTSTATUS NTAPI +IntWinstaOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters); + NTSTATUS FASTCALL IntValidateWindowStationHandle( HWINSTA WindowStation, @@ -106,4 +109,7 @@ IntGetFullWindowStationName( PWINSTATION_OBJECT FASTCALL IntGetWinStaObj(VOID); +BOOL FASTCALL +UserSetProcessWindowStation(HWINSTA hWindowStation); + /* EOF */ diff --git a/reactos/subsystems/win32/win32k/main/dllmain.c b/reactos/subsystems/win32/win32k/main/dllmain.c index a9202233735..1bff6e3f3b9 100644 --- a/reactos/subsystems/win32/win32k/main/dllmain.c +++ b/reactos/subsystems/win32/win32k/main/dllmain.c @@ -119,6 +119,7 @@ Win32kProcessCallback(struct _EPROCESS *Process, { DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql()); Win32Process->W32PF_flags |= W32PF_TERMINATED; + if (Win32Process->InputIdleEvent) { EngFreeMem((PVOID)Win32Process->InputIdleEvent); @@ -144,6 +145,9 @@ Win32kProcessCallback(struct _EPROCESS *Process, { LogonProcess = NULL; } + + UserSetProcessWindowStation(NULL); + } RETURN( STATUS_SUCCESS); @@ -220,25 +224,14 @@ Win32kThreadCallback(struct _ETHREAD *Thread, { if(hWinSta != NULL) { - if(Process != CsrProcess) + if(!UserSetProcessWindowStation(hWinSta)) { - HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL); - if(hProcessWinSta != NULL) - { - /* our process is already assigned to a different window station, we don't need the handle anymore */ - NtClose(hWinSta); - } - } - else - { - NtClose(hWinSta); + DPRINT1("Failed to set process window station\n"); } } if (hDesk != NULL) { - Win32Thread->rpdesk = NULL; - Win32Thread->hdesk = NULL; if (!IntSetThreadDesktop(hDesk, FALSE)) { DPRINT1("Unable to set thread desktop\n"); @@ -441,6 +434,8 @@ DriverEntry( CalloutData.ProcessCallout = Win32kProcessCallback; CalloutData.ThreadCallout = Win32kThreadCallback; CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch; + CalloutData.DesktopOkToCloseProcedure = IntDesktopOkToClose; + CalloutData.WindowStationOkToCloseProcedure = IntWinstaOkToClose; /* Register our per-process and per-thread structures. */ PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData); diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index 0a240ad7772..e414e7e55bf 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -168,6 +168,29 @@ IntDesktopObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters) IntFreeDesktopHeap(Desktop); } +NTSTATUS NTAPI +IntDesktopOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters) +{ + PTHREADINFO pti; + + pti = PsGetCurrentThreadWin32Thread(); + + if( pti == NULL) + { + /* This happens when we leak desktop handles */ + return TRUE; + } + + /* Do not allow the current desktop or the initial desktop to be closed */ + if( Parameters->Handle == pti->ppi->hdeskStartup || + Parameters->Handle == pti->hdesk) + { + return FALSE; + } + + return TRUE; +} + /* PRIVATE FUNCTIONS **********************************************************/ INIT_FUNCTION diff --git a/reactos/subsystems/win32/win32k/ntuser/winsta.c b/reactos/subsystems/win32/win32k/ntuser/winsta.c index d4f4643f4ed..b22a9d7e2ea 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winsta.c +++ b/reactos/subsystems/win32/win32k/ntuser/winsta.c @@ -187,6 +187,21 @@ IntWinStaObjectParse(PWIN32_PARSEMETHOD_PARAMETERS Parameters) return STATUS_OBJECT_TYPE_MISMATCH; } +NTSTATUS NTAPI +IntWinstaOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters) +{ + PPROCESSINFO ppi; + + ppi = PsGetCurrentProcessWin32Process(); + + if(Parameters->Handle == ppi->hwinsta) + { + return FALSE; + } + + return TRUE; +} + /* PRIVATE FUNCTIONS **********************************************************/ /* @@ -915,6 +930,57 @@ IntGetWinStaObj(VOID) return WinStaObj; } +BOOL FASTCALL +UserSetProcessWindowStation(HWINSTA hWindowStation) +{ + PPROCESSINFO ppi; + NTSTATUS Status; + HWINSTA hwinstaOld; + PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta; + + ppi = PsGetCurrentProcessWin32Process(); + + if(hWindowStation !=NULL) + { + Status = IntValidateWindowStationHandle( hWindowStation, + KernelMode, + 0, + &NewWinSta); + if (!NT_SUCCESS(Status)) + { + DPRINT("Validation of window station handle (0x%X) failed\n", + hWindowStation); + SetLastNtError(Status); + return FALSE; + } + } + + OldWinSta = ppi->prpwinsta; + hwinstaOld = ppi->hwinsta; + + /* + * FIXME - don't allow changing the window station if there are threads that are attached to desktops and own gui objects + */ + + InterlockedExchangePointer(&PsGetCurrentProcess()->Win32WindowStation, hWindowStation); + + ppi->prpwinsta = NewWinSta; + ppi->hwinsta = hWindowStation; + + + if(OldWinSta != NULL) + { + ObDereferenceObject(OldWinSta); + } + + if(hwinstaOld != NULL) + { + ZwClose(hwinstaOld); + } + + return TRUE; +} + /* * NtUserSetProcessWindowStation * @@ -934,44 +1000,15 @@ IntGetWinStaObj(VOID) BOOL APIENTRY NtUserSetProcessWindowStation(HWINSTA hWindowStation) { - PWINSTATION_OBJECT NewWinSta; - NTSTATUS Status; + BOOL ret; - DPRINT("About to set process window station with handle (0x%X)\n", - hWindowStation); + UserEnterExclusive(); - if(PsGetCurrentProcess() == CsrProcess) - { - DPRINT1("CSRSS is not allowed to change it's window station!!!\n"); - EngSetLastError(ERROR_ACCESS_DENIED); - return FALSE; - } + ret = UserSetProcessWindowStation(hWindowStation); - Status = IntValidateWindowStationHandle( - hWindowStation, - KernelMode, - 0, - &NewWinSta); + UserLeave(); - if (!NT_SUCCESS(Status)) - { - DPRINT("Validation of window station handle (0x%X) failed\n", - hWindowStation); - SetLastNtError(Status); - return FALSE; - } - - /* - * FIXME - don't allow changing the window station if there are threads that are attached to desktops and own gui objects - */ - - /* FIXME - dereference the old window station, etc... */ - InterlockedExchangePointer(&PsGetCurrentProcess()->Win32WindowStation, hWindowStation); - - DPRINT("PsGetCurrentProcess()->Win32WindowStation 0x%X\n", - PsGetCurrentProcess()->Win32WindowStation); - - return TRUE; + return ret; } /* From 4a05e4ef291c598995870aabea0273099d680209 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Tue, 22 Mar 2011 09:59:36 +0000 Subject: [PATCH 54/90] [win32k] - Simplify BuildWindowStationNameList a bit svn path=/trunk/; revision=51116 --- reactos/subsystems/win32/win32k/ntuser/winsta.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/winsta.c b/reactos/subsystems/win32/win32k/ntuser/winsta.c index b22a9d7e2ea..2f44707b070 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winsta.c +++ b/reactos/subsystems/win32/win32k/ntuser/winsta.c @@ -1110,21 +1110,13 @@ BuildWindowStationNameList( OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE DirectoryHandle; - UNICODE_STRING DirectoryName; + UNICODE_STRING DirectoryName = RTL_CONSTANT_STRING(WINSTA_ROOT_NAME); char InitialBuffer[256], *Buffer; ULONG Context, ReturnLength, BufferSize; DWORD EntryCount; POBJECT_DIRECTORY_INFORMATION DirEntry; WCHAR NullWchar; - /* - * Generate name of window station directory - */ - if (!IntGetFullWindowStationName(&DirectoryName, NULL, NULL)) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - /* * Try to open the directory. */ @@ -1140,8 +1132,6 @@ BuildWindowStationNameList( DIRECTORY_QUERY, &ObjectAttributes); - ExFreePool(DirectoryName.Buffer); - if (!NT_SUCCESS(Status)) { return Status; From 64e9e4c1963452322d7939b95a65f5b9597f8ea0 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 22 Mar 2011 12:41:52 +0000 Subject: [PATCH 55/90] [NTDLL] - Implement LdrpInitializeProcess(). Currently unused. - Add a whole bunch of supportive PE related code. Used only by the new code, which is not enabled yet in trunk. - Implement LdrpCheckForLoadedDll(). - Move on to usage of various global vars defined in the new code, rename some of them to match. - Almost no changes for the codepath in trunk. svn path=/trunk/; revision=51117 --- reactos/dll/ntdll/include/ntdllp.h | 1 + reactos/dll/ntdll/ldr/ldrinit.c | 698 +++++++++++++++++++++++++- reactos/dll/ntdll/ldr/ldrpe.c | 752 +++++++++++++++++++++++++++++ reactos/dll/ntdll/ldr/ldrutils.c | 257 +++++++++- reactos/dll/ntdll/ldr/startup.c | 20 +- reactos/dll/ntdll/ldr/utils.c | 28 +- 6 files changed, 1719 insertions(+), 37 deletions(-) diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index 097f8522d1c..a01a960cef2 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -26,6 +26,7 @@ extern RTL_CRITICAL_SECTION LdrpLoaderLock; extern BOOLEAN LdrpInLdrInit; extern LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]; extern BOOLEAN ShowSnaps; +extern UNICODE_STRING LdrpDefaultPath; /* ldrinit.c */ NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL); diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index 535bce90b8c..cccaa4ee4f3 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -19,31 +19,69 @@ HKEY ImageExecOptionsKey; HKEY Wow64ExecOptionsKey; UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"); UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); +UNICODE_STRING NtDllString = RTL_CONSTANT_STRING(L"ntdll.dll"); BOOLEAN LdrpInLdrInit; LONG LdrpProcessInitialized; +BOOLEAN LdrpLoaderLockInit; +BOOLEAN LdrpLdrDatabaseIsSetup; + +BOOLEAN LdrpDllValidation; PLDR_DATA_TABLE_ENTRY LdrpImageEntry; PUNICODE_STRING LdrpTopLevelDllBeingLoaded; extern PTEB LdrpTopLevelDllBeingLoadedTeb; // defined in rtlsupp.c! PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer; +PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry; -//RTL_BITMAP TlsBitMap; -//RTL_BITMAP TlsExpansionBitMap; -//RTL_BITMAP FlsBitMap; +RTL_BITMAP TlsBitMap; +RTL_BITMAP TlsExpansionBitMap; +RTL_BITMAP FlsBitMap; BOOLEAN LdrpImageHasTls; LIST_ENTRY LdrpTlsList; ULONG LdrpNumberOfTlsEntries; ULONG LdrpNumberOfProcessors; +PVOID NtDllBase; +LARGE_INTEGER RtlpTimeout; +BOOLEAN RtlpTimeoutDisable; +LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]; +LIST_ENTRY LdrpDllNotificationList; +HANDLE LdrpKnownDllObjectDirectory; +UNICODE_STRING LdrpKnownDllPath; +WCHAR LdrpKnownDllPathBuffer[128]; +UNICODE_STRING LdrpDefaultPath; -RTL_CRITICAL_SECTION LdrpLoaderLock; +PEB_LDR_DATA PebLdr; + +RTL_CRITICAL_SECTION_DEBUG LdrpLoaderLockDebug; +RTL_CRITICAL_SECTION LdrpLoaderLock = +{ + &LdrpLoaderLockDebug, + -1, + 0, + 0, + 0, + 0 +}; +RTL_CRITICAL_SECTION FastPebLock; BOOLEAN ShowSnaps; ULONG LdrpFatalHardErrorCount; +//extern LIST_ENTRY RtlCriticalSectionList; + VOID RtlpInitializeVectoredExceptionHandling(VOID); VOID NTAPI RtlpInitDeferedCriticalSection(VOID); +VOID RtlInitializeHeapManager(VOID); +extern BOOLEAN RtlpPageHeapEnabled; +extern ULONG RtlpDphGlobalFlags; + +NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase); +NTSTATUS NTAPI +LdrpInitializeProcess_(PCONTEXT Context, + PVOID SystemArgument1); + /* FUNCTIONS *****************************************************************/ @@ -455,12 +493,10 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) /* Show debug message */ if (ShowSnaps) { - DPRINT1("[%x,%x] LDR: Real INIT LIST for Process %wZ pid %u %0x%x\n", + DPRINT1("[%x,%x] LDR: Real INIT LIST for Process %wZ\n", NtCurrentTeb()->RealClientId.UniqueThread, NtCurrentTeb()->RealClientId.UniqueProcess, - Peb->ProcessParameters->ImagePathName, - NtCurrentTeb()->RealClientId.UniqueThread, - NtCurrentTeb()->RealClientId.UniqueProcess); + &Peb->ProcessParameters->ImagePathName); } /* Loop in order */ @@ -838,6 +874,644 @@ LdrpFreeTls(VOID) TlsVector); } +NTSTATUS +NTAPI +LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PULONG Options) +{ + UNIMPLEMENTED; + *Options = 0; + return STATUS_SUCCESS; +} + +VOID +NTAPI +LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry) +{ + UNIMPLEMENTED; +} + +NTSTATUS +NTAPI +LdrpInitializeProcess(IN PCONTEXT Context, + IN PVOID SystemArgument1) +{ + RTL_HEAP_PARAMETERS HeapParameters; + ULONG ComSectionSize; + //ANSI_STRING FunctionName = RTL_CONSTANT_STRING("BaseQueryModuleData"); + PVOID OldShimData; + OBJECT_ATTRIBUTES ObjectAttributes; + //UNICODE_STRING LocalFileName, FullImageName; + HANDLE SymLinkHandle; + //ULONG DebugHeapOnly; + UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString; + PPEB Peb = NtCurrentPeb(); + BOOLEAN IsDotNetImage = FALSE; + BOOLEAN FreeCurDir = FALSE; + //HKEY CompatKey; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + //LPWSTR ImagePathBuffer; + ULONG ConfigSize; + UNICODE_STRING CurrentDirectory; + ULONG ExecuteOptions; + ULONG HeapFlags; + PIMAGE_NT_HEADERS NtHeader; + LPWSTR NtDllName = NULL; + NTSTATUS Status; + NLSTABLEINFO NlsTable; + PIMAGE_LOAD_CONFIG_DIRECTORY LoadConfig; + PTEB Teb = NtCurrentTeb(); + PLIST_ENTRY ListHead; + PLIST_ENTRY NextEntry; + ULONG i; + PWSTR ImagePath; + ULONG DebugProcessHeapOnly = 0; + WCHAR FullNtDllPath[MAX_PATH]; + PLDR_DATA_TABLE_ENTRY NtLdrEntry; + PWCHAR Current; + + /* Set a NULL SEH Filter */ + RtlSetUnhandledExceptionFilter(NULL); + + /* Get the image path */ + ImagePath = Peb->ProcessParameters->ImagePathName.Buffer; + + /* Check if it's normalized */ + if (Peb->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_NORMALIZED) + { + /* Normalize it*/ + ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters); + } + + /* Create a unicode string for the Image Path */ + ImagePathName.Length = Peb->ProcessParameters->ImagePathName.Length; + ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR); + ImagePathName.Buffer = ImagePath; + + /* Get the NT Headers */ + NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress); + + /* Get the execution options */ + Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &ExecuteOptions); + + /* Check if this is a .NET executable */ + if (RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, + &ComSectionSize)) + { + /* Remeber this for later */ + IsDotNetImage = TRUE; + } + + /* Save the NTDLL Base address */ + NtDllBase = SystemArgument1; + + /* If this is a Native Image */ + if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE) + { + /* Then do DLL Validation */ + LdrpDllValidation = TRUE; + } + + /* Save the old Shim Data */ + OldShimData = Peb->pShimData; + + /* Clear it */ + Peb->pShimData = NULL; + + /* Save the number of processors and CS Timeout */ + LdrpNumberOfProcessors = Peb->NumberOfProcessors; + RtlpTimeout = Peb->CriticalSectionTimeout; + + /* Normalize the parameters */ + ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters); + ProcessParameters = Peb->ProcessParameters; + if (ProcessParameters) + { + /* Save the Image and Command Line Names */ + ImageFileName = ProcessParameters->ImagePathName; + CommandLine = ProcessParameters->CommandLine; + } + else + { + /* It failed, initialize empty strings */ + RtlInitUnicodeString(&ImageFileName, NULL); + RtlInitUnicodeString(&CommandLine, NULL); + } + + /* Initialize NLS data */ + RtlInitNlsTables(Peb->AnsiCodePageData, + Peb->OemCodePageData, + Peb->UnicodeCaseTableData, + &NlsTable); + + /* Reset NLS Translations */ + RtlResetRtlTranslations(&NlsTable); + + /* Get the Image Config Directory */ + LoadConfig = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, + &ConfigSize); + + /* Setup the Heap Parameters */ + RtlZeroMemory(&HeapParameters, sizeof(RTL_HEAP_PARAMETERS)); + HeapFlags = HEAP_GROWABLE; + HeapParameters.Length = sizeof(RTL_HEAP_PARAMETERS); + + /* Check if we have Configuration Data */ + if ((LoadConfig) && (ConfigSize == sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))) + { + /* FIXME: Custom heap settings and misc. */ + DPRINT1("We don't support LOAD_CONFIG data yet\n"); + } + + /* Check for custom affinity mask */ + if (Peb->ImageProcessAffinityMask) + { + /* Set it */ + Status = NtSetInformationProcess(NtCurrentProcess(), + ProcessAffinityMask, + &Peb->ImageProcessAffinityMask, + sizeof(Peb->ImageProcessAffinityMask)); + } + + /* Check if verbose debugging (ShowSnaps) was requested */ + ShowSnaps = TRUE;//Peb->NtGlobalFlag & FLG_SHOW_LDR_SNAPS; + + /* Start verbose debugging messages right now if they were requested */ + if (ShowSnaps) + { + DPRINT1("LDR: PID: 0x%x started - '%wZ'\n", + Teb->ClientId.UniqueProcess, + &CommandLine); + } + + /* If the timeout is too long */ + if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000)) + { + /* Then disable CS Timeout */ + RtlpTimeoutDisable = TRUE; + } + + /* Initialize Critical Section Data */ + RtlpInitDeferedCriticalSection(); + + /* Initialize VEH Call lists */ + RtlpInitializeVectoredExceptionHandling(); + + /* Set TLS/FLS Bitmap data */ + Peb->FlsBitmap = &FlsBitMap; + Peb->TlsBitmap = &TlsBitMap; + Peb->TlsExpansionBitmap = &TlsExpansionBitMap; + + /* Initialize FLS Bitmap */ + RtlInitializeBitMap(&FlsBitMap, + Peb->FlsBitmapBits, + FLS_MAXIMUM_AVAILABLE); + RtlSetBit(&FlsBitMap, 0); + + /* Initialize TLS Bitmap */ + RtlInitializeBitMap(&TlsBitMap, + Peb->TlsBitmapBits, + TLS_MINIMUM_AVAILABLE); + RtlSetBit(&TlsBitMap, 0); + RtlInitializeBitMap(&TlsExpansionBitMap, + Peb->TlsExpansionBitmapBits, + TLS_EXPANSION_SLOTS); + RtlSetBit(&TlsExpansionBitMap, 0); + + /* Initialize the Hash Table */ + for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++) + { + InitializeListHead(&LdrpHashTable[i]); + } + + /* Initialize the Loader Lock */ + //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList); + //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock; + UNIMPLEMENTED; + LdrpLoaderLockInit = TRUE; + + /* Check if User Stack Trace Database support was requested */ + if (Peb->NtGlobalFlag & FLG_USER_STACK_TRACE_DB) + { + DPRINT1("We don't support user stack trace databases yet\n"); + } + + /* Setup Fast PEB Lock */ + RtlInitializeCriticalSection(&FastPebLock); + Peb->FastPebLock = &FastPebLock; + //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection; + //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection; + + /* Setup Callout Lock and Notification list */ + //RtlInitializeCriticalSection(&RtlpCalloutEntryLock); + InitializeListHead(&LdrpDllNotificationList); + + /* For old executables, use 16-byte aligned heap */ + if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) && + (NtHeader->OptionalHeader.MinorSubsystemVersion < 51)) + { + HeapFlags |= HEAP_CREATE_ALIGN_16; + } + + /* Setup the Heap */ + RtlInitializeHeapManager(); + Peb->ProcessHeap = RtlCreateHeap(HeapFlags, + NULL, + NtHeader->OptionalHeader.SizeOfHeapReserve, + NtHeader->OptionalHeader.SizeOfHeapCommit, + NULL, + &HeapParameters); + + if (!Peb->ProcessHeap) + { + DPRINT1("Failed to create process heap\n"); + return STATUS_NO_MEMORY; + } + + /* Allocate an Activation Context Stack */ + Status = RtlAllocateActivationContextStack((PVOID *)&Teb->ActivationContextStackPointer); + if (!NT_SUCCESS(Status)) return Status; + + // FIXME: Loader private heap is missing + DPRINT1("Loader private heap is missing\n"); + + /* Check for Debug Heap */ + DPRINT1("Check for a debug heap is missing\n"); + if (FALSE) + { + /* Query the setting */ + Status = LdrQueryImageFileKeyOption(NULL,//hKey + L"DebugProcessHeapOnly", + REG_DWORD, + &DebugProcessHeapOnly, + sizeof(ULONG), + NULL); + + if (NT_SUCCESS(Status)) + { + /* Reset DPH if requested */ + if (RtlpPageHeapEnabled && DebugProcessHeapOnly) + { + RtlpDphGlobalFlags &= ~0x40; + RtlpPageHeapEnabled = FALSE; + } + } + } + + /* Build the NTDLL Path */ + FullPath.Buffer = FullNtDllPath; + FullPath.Length = 0; + FullPath.MaximumLength = sizeof(FullNtDllPath); + RtlInitUnicodeString(&NtSystemRoot, SharedUserData->NtSystemRoot); + RtlAppendUnicodeStringToString(&FullPath, &NtSystemRoot); + RtlAppendUnicodeToString(&FullPath, L"\\System32\\"); + + /* Open the Known DLLs directory */ + RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls"); + InitializeObjectAttributes(&ObjectAttributes, + &KnownDllString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenDirectoryObject(&LdrpKnownDllObjectDirectory, + DIRECTORY_QUERY | DIRECTORY_TRAVERSE, + &ObjectAttributes); + + /* Check if it exists */ + if (!NT_SUCCESS(Status)) + { + /* It doesn't, so assume System32 */ + LdrpKnownDllObjectDirectory = NULL; + RtlInitUnicodeString(&LdrpKnownDllPath, FullPath.Buffer); + LdrpKnownDllPath.Length -= sizeof(WCHAR); + } + else + { + /* Open the Known DLLs Path */ + InitializeObjectAttributes(&ObjectAttributes, + &KnownDllString, + OBJ_CASE_INSENSITIVE, + LdrpKnownDllObjectDirectory, + NULL); + Status = NtOpenSymbolicLinkObject(&SymLinkHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + /* Query the path */ + LdrpKnownDllPath.Length = 0; + LdrpKnownDllPath.MaximumLength = sizeof(LdrpKnownDllPathBuffer); + LdrpKnownDllPath.Buffer = LdrpKnownDllPathBuffer; + Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL); + NtClose(SymLinkHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status); + return Status; + } + } + } + + /* If we have process parameters, get the default path and current path */ + if (ProcessParameters) + { + /* Check if we have a Dll Path */ + if (ProcessParameters->DllPath.Length) + { + /* Get the path */ + LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath; + } + else + { + /* We need a valid path */ + LdrpInitFailure(STATUS_INVALID_PARAMETER); + } + + /* Set the current directory */ + CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath; + + /* Check if it's empty or invalid */ + if ((!CurrentDirectory.Buffer) || + (CurrentDirectory.Buffer[0] == UNICODE_NULL) || + (!CurrentDirectory.Length)) + { + /* Allocate space for the buffer */ + CurrentDirectory.Buffer = RtlAllocateHeap(Peb->ProcessHeap, + 0, + 3 * sizeof(WCHAR) + + sizeof(UNICODE_NULL)); + + /* Copy the drive of the system root */ + RtlMoveMemory(CurrentDirectory.Buffer, + SharedUserData->NtSystemRoot, + 3 * sizeof(WCHAR)); + CurrentDirectory.Buffer[3] = UNICODE_NULL; + CurrentDirectory.Length = 3 * sizeof(WCHAR); + CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR); + + FreeCurDir = TRUE; + } + else + { + /* Use the local buffer */ + CurrentDirectory.Length = NtSystemRoot.Length; + CurrentDirectory.Buffer = NtSystemRoot.Buffer; + } + } + + /* Setup Loader Data */ + Peb->Ldr = &PebLdr; + InitializeListHead(&PebLdr.InLoadOrderModuleList); + InitializeListHead(&PebLdr.InMemoryOrderModuleList); + InitializeListHead(&PebLdr.InInitializationOrderModuleList); + PebLdr.Length = sizeof(PEB_LDR_DATA); + PebLdr.Initialized = TRUE; + + /* Allocate a data entry for the Image */ + LdrpImageEntry = NtLdrEntry = LdrpAllocateDataTableEntry(Peb->ImageBaseAddress); + + /* Set it up */ + NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase); + NtLdrEntry->LoadCount = -1; + NtLdrEntry->EntryPointActivationContext = 0; + NtLdrEntry->FullDllName.Length = ImageFileName.Length; + NtLdrEntry->FullDllName.Buffer = ImageFileName.Buffer; + if (IsDotNetImage) + NtLdrEntry->Flags = LDRP_COR_IMAGE; + else + NtLdrEntry->Flags = 0; + + /* Check if the name is empty */ + if (!ImageFileName.Buffer[0]) + { + /* Use the same Base name */ + NtLdrEntry->BaseDllName = NtLdrEntry->BaseDllName; + } + else + { + /* Find the last slash */ + Current = ImageFileName.Buffer; + while (*Current) + { + if (*Current++ == '\\') + { + /* Set this path */ + NtDllName = Current; + } + } + + /* Did we find anything? */ + if (!NtDllName) + { + /* Use the same Base name */ + NtLdrEntry->BaseDllName = NtLdrEntry->FullDllName; + } + else + { + /* Setup the name */ + NtLdrEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName); + NtLdrEntry->BaseDllName.MaximumLength = NtLdrEntry->BaseDllName.Length + sizeof(WCHAR); + NtLdrEntry->BaseDllName.Buffer = (PWSTR)((ULONG_PTR)ImageFileName.Buffer + + (ImageFileName.Length - NtLdrEntry->BaseDllName.Length)); + } + } + + /* Processing done, insert it */ + LdrpInsertMemoryTableEntry(NtLdrEntry); + NtLdrEntry->Flags |= LDRP_ENTRY_PROCESSED; + + /* Now add an entry for NTDLL */ + NtLdrEntry = LdrpAllocateDataTableEntry(SystemArgument1); + NtLdrEntry->Flags = LDRP_IMAGE_DLL; + NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase); + NtLdrEntry->LoadCount = -1; + NtLdrEntry->EntryPointActivationContext = 0; + //NtLdrEntry->BaseDllName.Length = NtSystemRoot.Length; + //RtlAppendUnicodeStringToString(&NtSystemRoot, &NtDllString); + NtLdrEntry->BaseDllName.Length = NtDllString.Length; + NtLdrEntry->BaseDllName.MaximumLength = NtDllString.MaximumLength; + NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer; + + // FIXME: Full DLL name?! + + /* Processing done, insert it */ + LdrpNtDllDataTableEntry = NtLdrEntry; + LdrpInsertMemoryTableEntry(NtLdrEntry); + + /* Let the world know */ + if (ShowSnaps) + { + DPRINT1("LDR: NEW PROCESS\n"); + DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName); + DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory); + DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath); + } + + /* Link the Init Order List */ + InsertHeadList(&Peb->Ldr->InInitializationOrderModuleList, + &LdrpNtDllDataTableEntry->InInitializationOrderModuleList); + + /* Set the current directory */ + Status = RtlSetCurrentDirectory_U(&CurrentDirectory); + if (!NT_SUCCESS(Status)) + { + /* We failed, check if we should free it */ + if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory); + + /* Set it to the NT Root */ + CurrentDirectory = NtSystemRoot; + RtlSetCurrentDirectory_U(&CurrentDirectory); + } + else + { + /* We're done with it, free it */ + if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory); + } + + /* Check if we should look for a .local file */ + if (ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH) + { + /* FIXME */ + DPRINT1("We don't support .local overrides yet\n"); + } + + /* Check if the Application Verifier was enabled */ + if (Peb->NtGlobalFlag & FLG_POOL_ENABLE_TAIL_CHECK) + { + /* FIXME */ + DPRINT1("We don't support Application Verifier yet\n"); + } + + if (IsDotNetImage) + { + /* FIXME */ + DPRINT1("We don't support .NET applications yet\n"); + } + + /* FIXME: Load support for Terminal Services */ + if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) + { + /* Load kernel32 and call BasePostImportInit... */ + DPRINT1("Unimplemented codepath!\n"); + } + + /* Walk the IAT and load all the DLLs */ + LdrpWalkImportDescriptor(LdrpDefaultPath.Buffer, LdrpImageEntry); + + /* Check if relocation is needed */ + if (Peb->ImageBaseAddress != (PVOID)NtHeader->OptionalHeader.ImageBase) + { + DPRINT("LDR: Performing relocations\n"); + Status = LdrPerformRelocations(NtHeader, Peb->ImageBaseAddress); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LdrPerformRelocations() failed\n"); + return STATUS_INVALID_IMAGE_FORMAT; + } + } + + /* Lock the DLLs */ + ListHead = &Peb->Ldr->InLoadOrderModuleList; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) + { + NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + NtLdrEntry->LoadCount = -1; + NextEntry = NextEntry->Flink; + } + + /* Phase 0 is done */ + LdrpLdrDatabaseIsSetup = TRUE; + + /* Initialize TLS */ + Status = LdrpInitializeTls(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n", + Status); + return Status; + } + + /* FIXME Mark the DLL Ranges for Stack Traces later */ + + /* Notify the debugger now */ + if (Peb->BeingDebugged) + { + /* Break */ + DbgBreakPoint(); + + /* Update show snaps again */ + ShowSnaps = Peb->NtGlobalFlag & FLG_SHOW_LDR_SNAPS; + } + + /* Validate the Image for MP Usage */ + if (LdrpNumberOfProcessors > 1) LdrpValidateImageForMp(LdrpImageEntry); + + /* Check NX Options */ + if (SharedUserData->NXSupportPolicy == 1) + { + ExecuteOptions = 0xD; + } + else if (!SharedUserData->NXSupportPolicy) + { + ExecuteOptions = 0xA; + } + + /* Let Mm know */ + ZwSetInformationProcess(NtCurrentProcess(), + ProcessExecuteFlags, + &ExecuteOptions, + sizeof(ULONG)); + + /* Check if we had Shim Data */ + if (OldShimData) + { + /* Load the Shim Engine */ + Peb->AppCompatInfo = NULL; + //LdrpLoadShimEngine(OldShimData, ImagePathName, OldShimData); + DPRINT1("We do not support shims yet\n"); + } + else + { + /* Check for Application Compatibility Goo */ + //LdrQueryApplicationCompatibilityGoo(hKey); + DPRINT1("Querying app compat hacks is missing!\n"); + } + + /* + * FIXME: Check for special images, SecuROM, SafeDisc and other NX- + * incompatible images. + */ + + /* Now call the Init Routines */ + Status = LdrpRunInitializeRoutines(Context); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n", + Status); + return Status; + } + + /* FIXME: Unload the Shim Engine if it was loaded */ + + /* Check if we have a user-defined Post Process Routine */ + if (NT_SUCCESS(Status) && Peb->PostProcessInitRoutine) + { + DPRINT1("CP\n"); + /* Call it */ + Peb->PostProcessInitRoutine(); + } + + ///* Close the key if we have one opened */ + //if (hKey) NtClose(hKey); +DbgBreakPoint(); + /* Return status */ + return Status; +} + VOID NTAPI LdrpInitFailure(NTSTATUS Status) @@ -915,17 +1589,11 @@ LdrpInit(PCONTEXT Context, /* Let other code know we're initializing */ LdrpInLdrInit = TRUE; - /* Initialize Critical Section Data */ - RtlpInitDeferedCriticalSection(); - - /* Initialize VEH Call lists */ - RtlpInitializeVectoredExceptionHandling(); - /* Protect with SEH */ _SEH2_TRY { /* Initialize the Process */ - LoaderStatus = LdrpInitializeProcess(Context, + LoaderStatus = LdrpInitializeProcess_(Context, SystemArgument1); /* Check for success and if MinimumStackCommit was requested */ diff --git a/reactos/dll/ntdll/ldr/ldrpe.c b/reactos/dll/ntdll/ldr/ldrpe.c index 4e72d91e908..ddcaf617e50 100644 --- a/reactos/dll/ntdll/ldr/ldrpe.c +++ b/reactos/dll/ntdll/ldr/ldrpe.c @@ -30,6 +30,595 @@ LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, /* FUNCTIONS *****************************************************************/ +NTSTATUS +NTAPI +LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, + IN PLDR_DATA_TABLE_ENTRY ImportLdrEntry, + IN PIMAGE_IMPORT_DESCRIPTOR IatEntry, + IN BOOLEAN EntriesValid) +{ + PIMAGE_EXPORT_DIRECTORY ExportDirectory; + ULONG ExportSize; + PVOID Iat; + SIZE_T ImportSize; + ULONG IatSize; + //PPEB Peb = NtCurrentPeb(); + NTSTATUS Status; + PIMAGE_THUNK_DATA Thunk, OriginalThunk, FirstThunk; + LPSTR ImportName; + ULONG ForwarderChain; + PIMAGE_NT_HEADERS NtHeader; + PIMAGE_SECTION_HEADER SectionHeader; + ULONG i, Rva; + ULONG OldProtect; + + /* Get export directory */ + ExportDirectory = RtlImageDirectoryEntryToData(ExportLdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportSize); + + /* Make sure it has one */ + if (!ExportDirectory) return STATUS_INVALID_IMAGE_FORMAT; + + /* Get the IAT */ + Iat = RtlImageDirectoryEntryToData(ImportLdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IAT, + &IatSize); + ImportSize = IatSize; + + /* Check if we don't have one */ + if (!Iat) + { + /* Get the NT Header and the first section */ + NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase); + SectionHeader = IMAGE_FIRST_SECTION(NtHeader); + + /* Get the RVA of the import directory */ + Rva = NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + + /* Make sure we got one */ + if (Rva) + { + /* Loop all the sections */ + for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++) + { + /* Check if we are inside this section */ + if ((Rva >= SectionHeader->VirtualAddress) && + (Rva < (SectionHeader->VirtualAddress + + SectionHeader->SizeOfRawData))) + { + /* We are, so set the IAT here */ + Iat = (PVOID)((ULONG_PTR)(ImportLdrEntry->DllBase) + + SectionHeader->VirtualAddress); + + /* Set the size */ + IatSize = SectionHeader->Misc.VirtualSize; + + /* Deal with Watcom and other retarded compilers */ + if (!IatSize) + { + IatSize = SectionHeader->SizeOfRawData; + } + + /* Found it, get out */ + break; + } + + /* No match, move to the next section */ + ++SectionHeader; + } + } + + /* If we still don't have an IAT, that's bad */ + if (!Iat) return STATUS_INVALID_IMAGE_FORMAT; + + /* Set the right size */ + ImportSize = IatSize; + } + + /* Unprotect the IAT */ + Status = NtProtectVirtualMemory(NtCurrentProcess(), + &Iat, + &ImportSize, + PAGE_READWRITE, + &OldProtect); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if the Thunks are already valid */ + if (EntriesValid) + { + /* We'll only do forwarders. Get the import name */ + ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase + IatEntry->Name); + + /* Get the list of forwaders */ + ForwarderChain = IatEntry->ForwarderChain; + + /* Loop them */ + while (ForwarderChain != -1) + { + /* Get the cached thunk VA*/ + OriginalThunk = (PIMAGE_THUNK_DATA) + ((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->OriginalFirstThunk + + (ForwarderChain * sizeof(IMAGE_THUNK_DATA))); + + /* Get the first thunk */ + FirstThunk = (PIMAGE_THUNK_DATA) + ((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->FirstThunk + + (ForwarderChain * sizeof(IMAGE_THUNK_DATA))); + + /* Get the Forwarder from the thunk */ + ForwarderChain = (ULONG)FirstThunk->u1.Ordinal; + + /* Snap the thunk */ + Status = LdrpSnapThunk(ExportLdrEntry->DllBase, + ImportLdrEntry->DllBase, + OriginalThunk, + FirstThunk, + ExportDirectory, + ExportSize, + TRUE, + ImportName); + + /* Move to the next thunk */ + FirstThunk++; + + /* If we messed up, exit */ + if (!NT_SUCCESS(Status)) break; + } + } + else if (IatEntry->FirstThunk) + { + /* Full snapping. Get the First thunk */ + FirstThunk = (PIMAGE_THUNK_DATA) + ((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->FirstThunk); + + /* Get the NT Header */ + NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase); + + /* Get the Original thunk VA, watch out for weird images */ + if ((IatEntry->Characteristics < NtHeader->OptionalHeader.SizeOfHeaders) || + (IatEntry->Characteristics >= NtHeader->OptionalHeader.SizeOfImage)) + { + /* Reuse it, this is a strange linked file */ + OriginalThunk = FirstThunk; + } + else + { + /* Get the address from the field and convert to VA */ + OriginalThunk = (PIMAGE_THUNK_DATA) + ((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->OriginalFirstThunk); + } + + /* Get the Import name VA */ + ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->Name); + + /* Loop while it's valid */ + while (OriginalThunk->u1.AddressOfData) + { + /* Snap the Thunk */ + Status = LdrpSnapThunk(ExportLdrEntry->DllBase, + ImportLdrEntry->DllBase, + OriginalThunk, + FirstThunk, + ExportDirectory, + ExportSize, + TRUE, + ImportName); + + /* Next thunks */ + OriginalThunk++; + Thunk++; + + /* If we failed the snap, break out */ + if (!NT_SUCCESS(Status)) break; + } + } + + /* Protect the IAT again */ + NtProtectVirtualMemory(NtCurrentProcess(), + &Iat, + &ImportSize, + OldProtect, + &OldProtect); + + /* Also flush out the cache */ + NtFlushInstructionCache(NtCurrentProcess(), Iat, IatSize); + + /* Return to Caller */ + return Status; +} + +NTSTATUS +NTAPI +LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry, + IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry, + IN PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry) +{ + LPSTR ImportName = NULL, BoundImportName, ForwarderName; + NTSTATUS Status; + BOOLEAN AlreadyLoaded = FALSE, Stale; + PIMAGE_IMPORT_DESCRIPTOR ImportEntry; + PLDR_DATA_TABLE_ENTRY DllLdrEntry, ForwarderLdrEntry; + PIMAGE_BOUND_FORWARDER_REF ForwarderEntry; + PPEB Peb = NtCurrentPeb(); + ULONG i, IatSize; + + /* Get the name's VA */ + BoundImportName = (LPSTR)(BoundEntry + BoundEntry->OffsetModuleName); + + /* Show debug mesage */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ bound to %s\n", &LdrEntry->BaseDllName, BoundImportName); + } + + /* Load the module for this entry */ + Status = LdrpLoadImportModule(DllPath, + BoundImportName, + LdrEntry->DllBase, + &DllLdrEntry, + &AlreadyLoaded); + if (!NT_SUCCESS(Status)) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ failed to load import module %s; status = %x\n", + &LdrEntry->BaseDllName, + BoundImportName, + Status); + } + goto Quickie; + } + + /* Check if it wasn't already loaded */ + if (!AlreadyLoaded) + { + /* Add it to our list */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &DllLdrEntry->InInitializationOrderModuleList); + } + + /* Check if the Bound Entry is now invalid */ + if ((BoundEntry->TimeDateStamp != DllLdrEntry->TimeDateStamp) || + (DllLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE)) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ has stale binding to %s\n", + &DllLdrEntry->BaseDllName, + BoundImportName); + } + + /* Remember it's become stale */ + Stale = TRUE; + } + else + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ has correct binding to %s\n", + &DllLdrEntry->BaseDllName, + BoundImportName); + } + + /* Remember it's valid */ + Stale = FALSE; + } + + /* Get the forwarders */ + ForwarderEntry = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1); + + /* Loop them */ + for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++) + { + /* Get the name */ + ForwarderName = (LPSTR)(FirstEntry + ForwarderEntry->OffsetModuleName); + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ bound to %s via forwarder(s) from %wZ\n", + &LdrEntry->BaseDllName, + ForwarderName, + &DllLdrEntry->BaseDllName); + } + + /* Load the module */ + Status = LdrpLoadImportModule(DllPath, + ForwarderName, + LdrEntry->DllBase, + &ForwarderLdrEntry, + &AlreadyLoaded); + if (NT_SUCCESS(Status)) + { + /* Loaded it, was it already loaded? */ + if (!AlreadyLoaded) + { + /* Add it to our list */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &ForwarderLdrEntry->InInitializationOrderModuleList); + } + } + + /* Check if the Bound Entry is now invalid */ + if (!(NT_SUCCESS(Status)) || + (ForwarderEntry->TimeDateStamp != ForwarderLdrEntry->TimeDateStamp) || + (ForwarderLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE)) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ has stale binding to %s\n", + &ForwarderLdrEntry->BaseDllName, + ForwarderName); + } + + /* Remember it's become stale */ + Stale = TRUE; + } + else + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ has correct binding to %s\n", + &ForwarderLdrEntry->BaseDllName, + ForwarderName); + } + + /* Remember it's valid */ + Stale = FALSE; + } + + /* Move to the next one */ + ForwarderEntry++; + } + + /* Set the next bound entry to the forwarder */ + FirstEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)ForwarderEntry; + + /* Check if the binding was stale */ + if (Stale) + { + /* It was, so find the IAT entry for it */ + ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &IatSize); + + /* Make sure it has a name */ + while (ImportEntry->Name) + { + /* Get the name */ + ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name); + + /* Compare it */ + if (!_stricmp(ImportName, BoundImportName)) break; + + /* Move to next entry */ + ImportEntry += 1; + } + + /* If we didn't find a name, fail */ + if (!ImportEntry->Name) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: LdrpWalkImportTable - failing with" + "STATUS_OBJECT_NAME_INVALID due to no import descriptor name\n"); + } + + /* Return error */ + Status = STATUS_OBJECT_NAME_INVALID; + goto Quickie; + } + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: Stale Bind %s from %wZ\n", + ImportName, + &LdrEntry->BaseDllName); + } + + /* Snap the IAT Entry*/ + Status = LdrpSnapIAT(DllLdrEntry, + LdrEntry, + ImportEntry, + FALSE); + + /* Make sure we didn't fail */ + if (!NT_SUCCESS(Status)) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ failed to load import module %s; status = %x\n", + &LdrEntry->BaseDllName, + BoundImportName, + Status); + } + + /* Return */ + goto Quickie; + } + } + + /* All done */ + Status = STATUS_SUCCESS; + +Quickie: + /* Write where we are now and return */ + *BoundEntry = *FirstEntry; + return Status; +} + +NTSTATUS +NTAPI +LdrpHandleNewFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry, + IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry) +{ + PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry = BoundEntry; + NTSTATUS Status; + + /* Make sure we have a name */ + while (BoundEntry->OffsetModuleName) + { + /* Parse this descriptor */ + Status = LdrpHandleOneNewFormatImportDescriptor(DllPath, + LdrEntry, + BoundEntry, + FirstEntry); + if (!NT_SUCCESS(Status)) return Status; + } + + /* Done */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +LdrpHandleOneOldFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry, + IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry) +{ + //ULONG IatSize, i; + LPSTR ImportName; + NTSTATUS Status; + BOOLEAN AlreadyLoaded = FALSE, StaticEntriesValid = FALSE, SkipSnap = TRUE; + PLDR_DATA_TABLE_ENTRY DllLdrEntry; + PIMAGE_THUNK_DATA FirstThunk; + PPEB Peb = NtCurrentPeb(); + + /* Get the import name's VA */ + ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name); + + /* Get the first thunk */ + FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrEntry->DllBase + + ImportEntry->FirstThunk); + + /* Make sure it's valid */ + if (!FirstThunk->u1.Function) goto SkipEntry; + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %s used by %wZ\n", + ImportName, + &LdrEntry->BaseDllName); + } + + /* Load the module associated to it */ + Status = LdrpLoadImportModule(DllPath, + ImportName, + LdrEntry->DllBase, + &DllLdrEntry, + &AlreadyLoaded); + if (!NT_SUCCESS(Status)) return Status; + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: Snapping imports for %wZ from %s\n", + &LdrEntry->BaseDllName, + ImportName); + } + + /* Check if the image was bound when compiled */ + if (ImportEntry->OriginalFirstThunk) + { + /* It was, so check if the static IAT entries are still valid */ + if ((ImportEntry->TimeDateStamp) && + (ImportEntry->TimeDateStamp == DllLdrEntry->TimeDateStamp) && + (!(DllLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE))) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: Snap bypass %s from %wZ\n", + ImportName, + &LdrEntry->BaseDllName); + } + + /* + * They are still valid, so we can skip snapping them. + * Additionally, if we have no forwarders, we are totally + * done. + */ + if (ImportEntry->ForwarderChain == -1) + { + /* Totally skip LdrpSnapIAT */ + SkipSnap = TRUE; + } + else + { + /* Set this so LdrpSnapIAT will only do forwarders */ + StaticEntriesValid = TRUE; + } + } + } + + /* Check if it wasn't already loaded */ + if (!AlreadyLoaded) + { + /* Add the DLL to our list */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &DllLdrEntry->InInitializationOrderModuleList); + } + + /* Check if we should snap at all */ + if (!SkipSnap) + { + /* Now snap the IAT Entry */ + Status = LdrpSnapIAT(DllLdrEntry, + LdrEntry, + ImportEntry, + StaticEntriesValid); + if (!NT_SUCCESS(Status)) return Status; + } + +SkipEntry: + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +LdrpHandleOldFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry, + IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry) +{ + NTSTATUS Status; + + /* Check for Name and Thunk */ + while (ImportEntry->Name && ImportEntry->FirstThunk) + { + /* Parse this descriptor */ + Status = LdrpHandleOneOldFormatImportDescriptor(DllPath, + LdrEntry, + ImportEntry); + if (!NT_SUCCESS(Status)) return Status; + + /* Move to the next entry */ + ImportEntry++; + } + + /* Done */ + return STATUS_SUCCESS; +} + USHORT NTAPI LdrpNameToOrdinal(LPSTR ImportName, ULONG NumberOfNames, @@ -41,6 +630,169 @@ LdrpNameToOrdinal(LPSTR ImportName, return 0; } +NTSTATUS +NTAPI +LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry) +{ + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx; + PPEB Peb = NtCurrentPeb(); + NTSTATUS Status = STATUS_SUCCESS; + PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry = NULL; + PIMAGE_IMPORT_DESCRIPTOR ImportEntry; + ULONG BoundSize, IatSize; +DPRINT1("LdrpWalkImportDescriptor('%S' %x)\n", DllPath, LdrEntry); + /* Set up the Act Ctx */ + ActCtx.Size = sizeof(ActCtx); + ActCtx.Frame.Flags = ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID; + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + + /* Check if we have a manifest prober routine */ + if (LdrpManifestProberRoutine) + { + DPRINT1("We don't support manifests yet, much less prober routines\n"); + } + + /* Check if we failed above */ + if (!NT_SUCCESS(Status)) return Status; + + /* Get the Active ActCtx */ + Status = RtlGetActiveActivationContext(&LdrEntry->EntryPointActivationContext); + if (!NT_SUCCESS(Status)) return Status; + + /* Activate the ActCtx */ + RtlActivateActivationContextUnsafeFast(&ActCtx, + LdrEntry->EntryPointActivationContext); + + /* Check if we were directed */ + if (!(LdrEntry->Flags & LDRP_REDIRECTED)) + { + /* Get the Bound IAT */ + BoundEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, + &BoundSize); + } + + /* Get the regular IAT, for fallback */ + ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &IatSize); + + /* Check if we got at least one */ + if (BoundEntry || ImportEntry) + { + /* Do we have a Bound IAT */ + if (BoundEntry) + { + /* Handle the descriptor */ + Status = LdrpHandleNewFormatImportDescriptors(DllPath, + LdrEntry, + BoundEntry); + } + else + { + /* Handle the descriptor */ + Status = LdrpHandleOldFormatImportDescriptors(DllPath, + LdrEntry, + ImportEntry); + } + + /* Check the status of the handlers */ + if (NT_SUCCESS(Status)) + { + /* Check for Per-DLL Heap Tagging */ + if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAG_BY_DLL) + { + /* FIXME */ + DPRINT1("We don't support Per-DLL Heap Tagging yet!\n"); + } + + /* Check if Page Heap was enabled */ + if (Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS) + { + /* FIXME */ + DPRINT1("We don't support Page Heaps yet!\n"); + } + + /* Check if Application Verifier was enabled */ + if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAIL_CHECK) + { + /* FIXME */ + DPRINT1("We don't support Application Verifier yet!\n"); + } + + /* Just to be safe */ + Status = STATUS_SUCCESS; + } + } + + /* Release the activation context */ + RtlDeactivateActivationContextUnsafeFast(&ActCtx); + + /* Return status */ + return Status; +} + +NTSTATUS +NTAPI +LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, + IN LPSTR ImportName, + IN PVOID DllBase, + OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry, + OUT PBOOLEAN Existing) +{ + ANSI_STRING AnsiString; + PUNICODE_STRING ImpDescName; + NTSTATUS Status; + PPEB Peb = RtlGetCurrentPeb(); + PTEB Teb = NtCurrentTeb(); +DPRINT1("LdrpLoadImportModule('%S' '%s' %p %p %p)\n", DllPath, ImportName, DllBase, DataTableEntry, Existing); + /* Convert import descriptor name to unicode string */ + ImpDescName = &Teb->StaticUnicodeString; + RtlInitAnsiString(&AnsiString, ImportName); + Status = RtlAnsiStringToUnicodeString(ImpDescName, &AnsiString, FALSE); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if it's loaded */ + if (LdrpCheckForLoadedDll(DllPath, + ImpDescName, + TRUE, + FALSE, + DataTableEntry)) + { + /* It's already existing in the list */ + *Existing = TRUE; + return STATUS_SUCCESS; + } + + /* We're loading it for the first time */ + *Existing = FALSE; + + /* Map it */ + Status = LdrpMapDll(DllPath, + ImpDescName->Buffer, + NULL, + NULL, + TRUE, + FALSE, + DataTableEntry); + + if (!NT_SUCCESS(Status)) return Status; + + /* Walk its import descriptor table */ + Status = LdrpWalkImportDescriptor(DllPath, + *DataTableEntry); + if (!NT_SUCCESS(Status)) + { + /* Add it to the in-init-order list in case of failure */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &(*DataTableEntry)->InInitializationOrderModuleList); + } + + return Status; +} NTSTATUS NTAPI diff --git a/reactos/dll/ntdll/ldr/ldrutils.c b/reactos/dll/ntdll/ldr/ldrutils.c index b45ca1a21ae..8c2783755ae 100644 --- a/reactos/dll/ntdll/ldr/ldrutils.c +++ b/reactos/dll/ntdll/ldr/ldrutils.c @@ -16,7 +16,6 @@ /* GLOBALS *******************************************************************/ PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache; -LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]; #define LDR_GET_HASH_ENTRY(x) (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1)) @@ -217,7 +216,261 @@ LdrpCheckForLoadedDll(IN PWSTR DllPath, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry) { - UNIMPLEMENTED; + ULONG HashIndex; + PLIST_ENTRY ListHead, ListEntry; + PLDR_DATA_TABLE_ENTRY CurEntry; + BOOLEAN FullPath = FALSE; + PWCHAR wc; + WCHAR NameBuf[266]; + UNICODE_STRING FullDllName, NtPathName; + ULONG Length; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + HANDLE FileHandle, SectionHandle; + IO_STATUS_BLOCK Iosb; + PVOID ViewBase = NULL; + SIZE_T ViewSize = 0; + PIMAGE_NT_HEADERS NtHeader, NtHeader2; +DPRINT1("LdrpCheckForLoadedDll('%S' '%wZ' %d %d %p)\n", DllPath, DllName, Flag, RedirectedDll, LdrEntry); + /* Check if a dll name was provided */ + if (!DllName->Buffer || !DllName->Buffer[0]) return FALSE; + + /* Look in the hash table if flag was set */ +lookinhash: + if (Flag) + { + /* Get hash index */ + HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]); + + /* Traverse that list */ + ListHead = &LdrpHashTable[HashIndex]; + ListEntry = ListHead->Flink; + while (ListEntry != ListHead) + { + /* Get the current entry */ + CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, HashLinks); + + /* Check base name of that module */ + if (RtlEqualUnicodeString(DllName, &CurEntry->BaseDllName, TRUE)) + { + /* It matches, return it */ + *LdrEntry = CurEntry; + return TRUE; + } + + /* Advance to the next entry */ + ListEntry = ListEntry->Flink; + } + + /* Module was not found, return failure */ + return FALSE; + } + + /* Check if there is a full path in this DLL */ + wc = DllName->Buffer; + while (*wc) + { + /* Check for a slash in the current position*/ + if (*wc == L'\\' || *wc == L'/') + { + /* Found the slash, so dll name contains path */ + FullPath = TRUE; + + /* Setup full dll name string */ + FullDllName.Buffer = NameBuf; + + Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer, + DllName->Buffer, + NULL, + sizeof(NameBuf) - sizeof(UNICODE_NULL), + FullDllName.Buffer, + NULL); + + /* Check if that was successful */ + if (!Length || Length > sizeof(NameBuf) - sizeof(UNICODE_NULL)) + { + if (ShowSnaps) + { + DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %ws: 0x%08x\n", + DllName->Buffer, Length); + } + + /* Return failure */ + return FALSE; + } + + /* Full dll name is found */ + FullDllName.Length = Length; + FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL); + break; + } + + wc++; + } + + /* Go check the hash table */ + if (!FullPath) + { + Flag = TRUE; + goto lookinhash; + } + + /* Now go through the InLoadOrder module list */ + ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + ListEntry = ListHead->Flink; + + while (ListEntry != ListHead) + { + /* Get the containing record of the current entry and advance to the next one */ + CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + ListEntry = ListEntry->Flink; + + /* Check if it's already being unloaded */ + if (!CurEntry->InMemoryOrderModuleList.Flink) continue; + + /* Check if name matches */ + if (RtlEqualUnicodeString(&FullDllName, + &CurEntry->FullDllName, + TRUE)) + { + /* Found it */ + *LdrEntry = CurEntry; + + /* Find activation context */ + Status = RtlFindActivationContextSectionString(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, DllName, NULL); + if (!NT_SUCCESS(Status)) + return FALSE; + else + return TRUE; + } + } + + /* The DLL was not found in the load order modules list. Perform a complex check */ + + /* Convert given path to NT path */ + if (!RtlDosPathNameToNtPathName_U(FullDllName.Buffer, + &NtPathName, + NULL, + NULL)) + { + /* Fail if conversion failed */ + return FALSE; + } + + /* Initialize object attributes and open it */ + InitializeObjectAttributes(&ObjectAttributes, + &NtPathName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + SYNCHRONIZE | FILE_EXECUTE, + &ObjectAttributes, + &Iosb, + FILE_SHARE_READ | FILE_SHARE_DELETE, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); + + /* Free NT path name */ + RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer); + + /* If opening the file failed - return failure */ + if (!NT_SUCCESS(Status)) return FALSE; + + /* Create a section for this file */ + Status = NtCreateSection(&SectionHandle, + SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_WRITE, + NULL, + NULL, + PAGE_EXECUTE, + SEC_COMMIT, + FileHandle); + + /* Close file handle */ + NtClose(FileHandle); + + /* If creating section failed - return failure */ + if (!NT_SUCCESS(Status)) return FALSE; + + /* Map view of this section */ + Status = ZwMapViewOfSection(SectionHandle, + NtCurrentProcess(), + &ViewBase, + 0, + 0, + NULL, + &ViewSize, + ViewShare, + 0, + PAGE_EXECUTE); + /* Close section handle */ + NtClose(SectionHandle); + + /* If section mapping failed - return failure */ + if (!NT_SUCCESS(Status)) return FALSE; + + /* Get pointer to the NT header of this section */ + NtHeader = RtlImageNtHeader(ViewBase); + if (!NtHeader) + { + /* Unmap the section and fail */ + NtUnmapViewOfSection(NtCurrentProcess(), ViewBase); + return FALSE; + } + + /* Go through the list of modules */ + ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + ListEntry = ListHead->Flink; + + while (ListEntry != ListHead) + { + CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + ListEntry = ListEntry->Flink; + + /* Check if it's already being unloaded */ + if (!CurEntry->InMemoryOrderModuleList.Flink) continue; + + _SEH2_TRY + { + /* Check if timedate stamp and sizes match */ + if (CurEntry->TimeDateStamp == NtHeader->FileHeader.TimeDateStamp && + CurEntry->SizeOfImage == NtHeader->OptionalHeader.SizeOfImage) + { + /* Time, date and size match. Let's compare their headers */ + NtHeader2 = RtlImageNtHeader(CurEntry->DllBase); + + if (RtlCompareMemory(NtHeader2, NtHeader, sizeof(IMAGE_NT_HEADERS))) + { + /* Headers match too! Finally ask the kernel to compare mapped files */ + Status = ZwAreMappedFilesTheSame(CurEntry->DllBase, ViewBase); + + if (!NT_SUCCESS(Status)) + { + _SEH2_YIELD(continue;) + } + else + { + /* This is our entry! */ + *LdrEntry = CurEntry; + + /* Unmap the section */ + NtUnmapViewOfSection(NtCurrentProcess(), ViewBase); + + _SEH2_YIELD(return TRUE;) + } + } + } + } + _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(break;) + } + _SEH2_END; + } + + /* Unmap the section */ + NtUnmapViewOfSection(NtCurrentProcess(), ViewBase); + return FALSE; } diff --git a/reactos/dll/ntdll/ldr/startup.c b/reactos/dll/ntdll/ldr/startup.c index 731842ac26e..f063aefdc0d 100644 --- a/reactos/dll/ntdll/ldr/startup.c +++ b/reactos/dll/ntdll/ldr/startup.c @@ -17,13 +17,15 @@ VOID RtlInitializeHeapManager(VOID); VOID LdrpInitLoader(VOID); extern PTEB LdrpTopLevelDllBeingLoadedTeb; +VOID NTAPI RtlpInitDeferedCriticalSection(VOID); +VOID RtlpInitializeVectoredExceptionHandling(VOID); /* GLOBALS *******************************************************************/ extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry; -static RTL_CRITICAL_SECTION PebLock; -static RTL_BITMAP TlsBitMap; -static RTL_BITMAP TlsExpansionBitMap; +extern RTL_CRITICAL_SECTION FastPebLock; +extern RTL_BITMAP TlsBitMap; +extern RTL_BITMAP TlsExpansionBitMap; #define VALUE_BUFFER_SIZE 256 @@ -309,7 +311,7 @@ finish: NTSTATUS NTAPI -LdrpInitializeProcess(PCONTEXT Context, +LdrpInitializeProcess_(PCONTEXT Context, PVOID SystemArgument1) { PIMAGE_NT_HEADERS NTHeaders; @@ -372,6 +374,9 @@ LdrpInitializeProcess(PCONTEXT Context, Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors; + /* Initialize Critical Section Data */ + RtlpInitDeferedCriticalSection(); + /* Load execution options */ LoadImageFileExecutionOptions(Peb); @@ -430,9 +435,12 @@ LdrpInitializeProcess(PCONTEXT Context, ZwTerminateProcess(NtCurrentProcess(), STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE); } + /* initialized vectored exception handling */ + RtlpInitializeVectoredExceptionHandling(); + /* initalize peb lock support */ - RtlInitializeCriticalSection(&PebLock); - Peb->FastPebLock = &PebLock; + RtlInitializeCriticalSection(&FastPebLock); + Peb->FastPebLock = &FastPebLock; /* initialize tls bitmaps */ RtlInitializeBitMap(&TlsBitMap, Peb->TlsBitmapBits, TLS_MINIMUM_AVAILABLE); diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 2f660dacdbe..c9bb89bbb51 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -32,8 +32,8 @@ #endif static BOOLEAN LdrpDllShutdownInProgress = FALSE; -static HANDLE LdrpKnownDllsDirHandle = NULL; -static UNICODE_STRING LdrpKnownDllPath = {0, 0, NULL}; +extern HANDLE LdrpKnownDllObjectDirectory; +extern UNICODE_STRING LdrpKnownDllPath; static PLDR_DATA_TABLE_ENTRY LdrpLastModule = NULL; extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry; @@ -231,13 +231,13 @@ LdrpInitLoader(VOID) OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = NtOpenDirectoryObject(&LdrpKnownDllsDirHandle, + Status = NtOpenDirectoryObject(&LdrpKnownDllObjectDirectory, DIRECTORY_QUERY | DIRECTORY_TRAVERSE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenDirectoryObject() failed (Status %lx)\n", Status); - LdrpKnownDllsDirHandle = NULL; + LdrpKnownDllObjectDirectory = NULL; return; } @@ -249,8 +249,8 @@ LdrpInitLoader(VOID) MAX_PATH * sizeof(WCHAR)); if (LinkTarget.Buffer == NULL) { - NtClose(LdrpKnownDllsDirHandle); - LdrpKnownDllsDirHandle = NULL; + NtClose(LdrpKnownDllObjectDirectory); + LdrpKnownDllObjectDirectory = NULL; return; } @@ -259,7 +259,7 @@ LdrpInitLoader(VOID) InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, - LdrpKnownDllsDirHandle, + LdrpKnownDllObjectDirectory, NULL); Status = NtOpenSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_ALL_ACCESS, @@ -267,8 +267,8 @@ LdrpInitLoader(VOID) if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&LinkTarget); - NtClose(LdrpKnownDllsDirHandle); - LdrpKnownDllsDirHandle = NULL; + NtClose(LdrpKnownDllObjectDirectory); + LdrpKnownDllObjectDirectory = NULL; return; } @@ -279,8 +279,8 @@ LdrpInitLoader(VOID) if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&LinkTarget); - NtClose(LdrpKnownDllsDirHandle); - LdrpKnownDllsDirHandle = NULL; + NtClose(LdrpKnownDllObjectDirectory); + LdrpKnownDllObjectDirectory = NULL; } RtlCreateUnicodeString(&LdrpKnownDllPath, @@ -431,7 +431,7 @@ LdrpMapKnownDll(IN PUNICODE_STRING DllName, DPRINT("LdrpMapKnownDll() called\n"); - if (LdrpKnownDllsDirHandle == NULL) + if (LdrpKnownDllObjectDirectory == NULL) { DPRINT("Invalid 'KnownDlls' directory\n"); return STATUS_UNSUCCESSFUL; @@ -442,7 +442,7 @@ LdrpMapKnownDll(IN PUNICODE_STRING DllName, InitializeObjectAttributes(&ObjectAttributes, DllName, OBJ_CASE_INSENSITIVE, - LdrpKnownDllsDirHandle, + LdrpKnownDllObjectDirectory, NULL); Status = NtOpenSection(SectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, @@ -1189,7 +1189,7 @@ LdrGetExportByName(PVOID BaseAddress, * NOTE * */ -static NTSTATUS +NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase) { From 4fb00286d50dfcd1a373a920f2d4af644aefb030 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 22 Mar 2011 16:27:41 +0000 Subject: [PATCH 56/90] [RTL/HEAP] - Thomas Faber: Use macro instead of manually removing item from the list. See issue #6016 for more details. svn path=/trunk/; revision=51119 --- reactos/lib/rtl/heap.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/reactos/lib/rtl/heap.c b/reactos/lib/rtl/heap.c index 110e68b0993..59e1fa7d97f 100644 --- a/reactos/lib/rtl/heap.c +++ b/reactos/lib/rtl/heap.c @@ -341,18 +341,9 @@ RtlpRemoveFreeBlock(PHEAP Heap, BOOLEAN NoFill) { SIZE_T Result, RealSize; - PLIST_ENTRY OldBlink, OldFlink; - // FIXME: Maybe use RemoveEntryList? - - /* Remove the free block */ - OldFlink = FreeEntry->FreeList.Flink; - OldBlink = FreeEntry->FreeList.Blink; - OldBlink->Flink = OldFlink; - OldFlink->Blink = OldBlink; - - /* Update the freelists bitmap */ - if ((OldFlink == OldBlink) && + /* Remove the free block and update the freelists bitmap */ + if (RemoveEntryList(&FreeEntry->FreeList) && (Dedicated || (!Dedicated && FreeEntry->Size < HEAP_FREELISTS))) { RtlpClearFreeListsBit(Heap, FreeEntry); From cc6c8e90e246f9083e3cc1f1407f2a22af9a8dbc Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 22 Mar 2011 16:35:51 +0000 Subject: [PATCH 57/90] [NTOS/KE] - Remove VirtualBox SYSENTER-hack added in r50991. - Bring back NT-compatible SYSENTER support detection changed in r50991. svn path=/trunk/; revision=51120 --- reactos/ntoskrnl/ke/i386/cpu.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 38539b11e70..693701b13af 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -303,17 +303,10 @@ KiGetFeatureBits(VOID) /* Remove support for correct PTE support. */ FeatureBits &= ~KF_WORKING_PTE; } - - /* Virtualbox claims to have no SYSENTER support, - * which is false for processors >= Pentium Pro */ - if(Prcb->CpuType >= 6) - { - Reg[3] |= 0x800; - } - /* Check if the CPU is too old to support SYSENTER, - * See Intel CPUID instruction manual for details*/ - if ((Reg[0] & 0x0FFF3FFF) < 0x00000633) + /* Check if the CPU is too old to support SYSENTER */ + if ((Prcb->CpuType < 6) || + ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303))) { /* Disable it */ Reg[3] &= ~0x800; From d312252d261047cdd94736d698ee25f3f37db974 Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Wed, 23 Mar 2011 11:44:35 +0000 Subject: [PATCH 58/90] [NTOS/INBV] - Update boot screen copyright year. svn path=/trunk/; revision=51121 --- reactos/ntoskrnl/inbv/logo/1.bmp | Bin 20504 -> 21640 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/reactos/ntoskrnl/inbv/logo/1.bmp b/reactos/ntoskrnl/inbv/logo/1.bmp index d13c48d16c07e2c5fb1d83be380c54637d2ddcf5..05b139a2fe626e083739ee9195a97ba85b3c1b84 100644 GIT binary patch literal 21640 zcmeI4e{@^tdEeiAd3}9_;D8q(!!V4dP@?Dhq&W>qxUkarSY9Ko>3VjSwW75(JsTy| zmw+PM=~jyLk}h_Yf&imhcHP1N!(%z=j!J@TopnuY6XK4~ys-iaN`KXBLXp;*9#>9D zfQ~y)@@U+Bp7(;Jl(c{BukM`1Iv_#d-tY7K$NRkR_0Rs(>`|rvJI&8~cs*e%b{(qo8@rj>O|LjxU%KL1eO8)C#R%5^ZFV%D7!)p3J zOsN0*(l^wfRsN$|u2$4vtW?$Y?|oOj`#=9iHTd@xaQqL{({=;zsl#W>fENF z9oSSi{TI|@?;qj=|(w;HXxeA@lMZyJxNg34*S@2YLOZc)8!*VVgf&lAqm&_E1( zbBAiERXqkbf^*Z|Y~{DTsiuXtwdV!A;G<2tB6FZ6*h zh|HD9yQx0G>yUiv8k+%K=T^FV^tHYUsr&uldnmsncZXUwRm&w5E1I@^)xOzs#RrIg z!sjN!L-%c=D;V1^?(C9_Zu`X2`nP}PR!v7*{U=o@FTPC(7&>sttmz^=O9+faWJ*tV-xof_OTcvgklHupRssL1*Q z`R$mS=bi`!KGm6bUR7T|q_*N)ago#xZ}nmsE$Pn|jGSr=J|<*dTzd%h{t*XP{G+unqZGCj}%RUsF@;R;QlbiUki^YG(Jm3Al zgvtRyjR$&r;MZDyJH}`7d4yL(T?#bgv=Rhe+^Hk%0beZJYWv;Xdne3`y$#}NFMo@Q z8|u%wZ%QM`yT2=o+`|>zYefdb!i6t!)=&>{$M!dSUWo9$QTXA{Ti$k+`HAgMk?Fur zJl`ayof}vjyLE07;@TQSG&~zt(R>Dqu~yaUzouVYWj*j3wr$0SolU#`Ci>O#HPlr& z5$v6qz3HY^ZwPqellH z<@fFQIyO6l*xaWMwf0I*0R39vwNMcB;sgGkr+3ip7X;mYVNZ9Q5%M+em(LUVW7fyzADWAh$bXzx+H1{l*piZwDnQA!@wc`d^3>XW>?dy zvsLYJTdwI>Z;Wp?MZwz~x9<3dBXRRF?aSJqcRWGM{Pg{U_A?(JH2z!Eg}xge{P4BE z%?pAE+6Ri{8KO`7D*RZjzWh9QW9O&+E4~yo6|w7E-8ih~nvYr~*2QN(1A@fH&+uM; zf91!&f2@bU!w+uY*JdI&TUVo0`Nm=)*{!zlm+jB5sZp+o{P^?#OFjIsK7SmCK_2=` zozckB_GA9jw3RCSp+E8)Q{67_TF%z}O0VQOpDd`t#^ZH={fu+~{-%6?$Kx~Qsb6o$ zAAfFU?m2ol{4~I$V=?Ia$*|@pL%y=Mdg&-E`wH)!LB%3~zgo_Rd~-oQ_a(pH6D}+3 z4_w}T*eRPY-HN5`J^s67SksR9=1s8Ahr!u$1;_j{pM4$fK;fGYx!fz5=1iz;KJ(@+ z9EpUqBCHS2`!`Q0GhO#z<^Hhr8F|-8^V@!#v`xRUhxhJ1y^c?o5%AXbeHgzob1$q(52I*0ieFz(3 zFFwB^J?nXFK;2cg?cdbjx4dz)Ne5i#j`G}tV)>sb|B1#o%HNW2?UwQjKSbvcniCET z{~f95wprI}4(L50bkJ8oN9fD<`{0M`kw@@8Rena{FOKoGa<}HD{Deqtef3+nOH=oI zHI+S}a=rD~7FSzW-s8PpM`QBW`7Qa&4)_6I^lZ$$;?fV;ABJzichHmI|H8|=_`-*1 zh2Pdk{Z9UBK^Cwghd>s&_VSI!v+pc_UE$TXG4qnf3zc1s_mNj_#}lmx-eWfe&p~#< z3yW=8x9;NoB>d2~hCc_+2g>4|ADFuxNhBAf^X~{!2<-{dogm5k9VF|EFKbHWFDT@- zK2Y985$oV@n$P;%a#aLOL1_U+-tVH6|C4+#Ru+^`{Se9_{~9P=M8hT>3|E8=5L*3x zTq`RLWn1N^6{`>HYkwm5fAtnw#2Q!p#H=e7hX><`}QzbZ%~p!jrPqg#=L1M7?SZMlpHi@fN&>QG?e@F8EB{yT!R?aREs zB}Q(=lc+Sm3f_h5JDEiATKzAmFdT5Fbw&5KL8M)QGr2$bE8-6}OJA#TkWALVbpw_e;5Ndy1dvu)j1u;m@1$Cn>mzZIF-)m)K3 z;TrTW!}PLQ;h;bO%-F zdm7(#_$+dv*GOEU`k{$ds-CUzb%|cH{7r3_uf6nx9dyyNLG(%mqblA&6X$fL?A4X> zF+LmI!TI7V8pk0Q!>2X#$G78%H^SHbyVbizSMMj9)!UHj&Dvda<*1L8KTC!q61z28 z`J1<+g~;e+8<<9EQzY-T%&@M1ese{{C_Cf$i-3jh*Z(-dg^q4nVEAXQ`ueUUhetYAIqmEd207A@e`wdQw{Fi^^@gqh`&4LOu1L?`s%mj zt~=4l?RPzZ@9x~?w3O#QE1LdgEFo6^+??DMx~(?L=RGH}ZEtWN5;&hKzx*Io{pYu< zdI&n2>fD=JGPBk7&F`Ji+;M#juB6*&|93mx29*D~`uXy=x373zsy zpQrPAV*48GXRqg7^{X0}Z$Bh`)=TtR%DQ8Qn0@Iw)EnvxSi;)r=j`$FbKSb1`}^;c znOV4|aY~u4Wi&)%a7$-tn64c)jbGut{B~R%&)wqNEmF3!qiu0aU>*oXf04gKQDwLF z#Q9jRdXKAa$W=~T+{@Tm%d_H6^qfP zF4xOFb{n7DRdX_2v?iUZ3Kui+1O4v3STx#mAnr{#RjU#%niZS-rt^J<#3nD>@QTW+ zDyveoGLC1Zl$|RIk_uPy$)0$$muwe}LzZ#5aw^3_HtZ=o%QbRW(G&XMSRHANQn0*m zT!oWfic3HV6_Wk&{p#b&)LKpCG;;B|jF$|>t%QnrxykBc;kaN(j*LW8la->ERCe4v z;6%+Bws5>uuE>2>1sf@=&%FzJhJ0fsgoagwsuef)bA68;w>7)qh>#-3EMLV;Y`&;mu(3zleJRN zu#?E;2r3#*AO_mc*zgoJ$owI}M443;D?aBX<57dXAqNk{=s1^^QQ<5)=+jk4kln=D z%hifKjc2)q3^&B!p-J&^q&M?$+h;``mmH?0H`Abpidk_{+qI%9ygwRGq;gi#p2m9B z^-D7wu$$;Z8Tf6u+j`lUd_P!73mA^}k2>r7=GE;)4xB8tOQK;ay1_x$|C+0$ipSvjXo2V^bvNC6R>h!sx!zdM_rbfMyGCNN?$@fb4&IID<9Cs`3VA~~ z4|1_~gN{{DPIhc$$U3b$M^67zdbX;u(IURrgG1rzA)>$rLq)1@_>BrN2fDoMj`U@U z56UQJRVZU-nMyB;Z!PBG)Uy*<+{qTJHLKC2mNiGM5o<`bk0sNWYm0<-prKH_C!U@K zh&*5wv!RSc3qaKN_57eKnU+_?@Fw5z*NHt3j}>%#G*^@uvnxpvO?71_E~13@GegAO zm_n+Kk+Edza&4WtkEAfm&=DXJC2^UtJbYEh)KHQByOPneK`Yjgt2X>fCf-jdt4I%4 zA)v(WpIJOZ@*B$)r)Mv&)f-!xR1po1X1)8CAydqr{zn*PC(ay*NSyV966=YlCjCa0 z$Q6mGG%+Nq*4KqM>X7(jNShxIvewaAa;RucTO}1*-*K|)?$PY&#PgcaSmyLE zw)Mvk>a2n^LPy#AiJFigGYq>@t5&>iT2`C*j#I-!V&avZF-g8vbd&eec1gu%W-nIP zYFDRoC|||$-r0I>X}W+GN35(wu8vH}#{@Cum7Lp_Uam<7$oB#SqDP*ltp^+hDqTz5cPkg$a#B57S{2i}6 zZfy4!G2`H5wOAEDga_M=wvp0QC{>)O)>*u$&P(2xs^z)G@=~=lZHu#{@%GTwMO;D= zOP$$Fa$FQB@yWU&Mw|%V8Fz<5G+nLaW}6f&gDi}%g^0>EDEKOT$vazJnsXM(43SbM zbpeGFbKDD>3vT=L|akSb(cbs*q?b zH}09NQSrc*ByhL^Sgmj}WSyUH8ywU-<4%hbk1x$HWbu6zgq^`hqDd4*6 zbm}rp^H+9sq_?S)iE0uZp4rw(d-Rj=oDhS$cntLnr%+ZlXH8(g87Ksr-`m(KRj;mn z$76bhj?qc1l<@+1GBNpW%*=>p;6LdVtNC62@t8s~AzFumYfw|9m`mi&l$Tc5YEE56 zYFC$6*E6SdR;yhtm++ogDepaxFmuyErXR&YkK;Gkbz(7@I9bg{n;L45o~q`PiAiLL zhz!!Dk^iu(f{IhVIKOJuoQ7GmR-v?zsw0B3mQ?3lX?9A?yuLVHbflKpS?r77Yu||{ z(z`UAXs$};R*qfUo#sLPaCzjycdxLidR+mVtJ|Jos>Mku~ed} z*jXD{vi}A;baImwK}AJcnrph!pRH!7XUY+YphdOS5{1Q6XUf*Ri9ArMJ2m?7Kx=kw zV_C9&B+tqRn-gdt99ThVe&Ry<9MycBqVSja8UFNvYtAFZ=!%4JTg(<1XHrdKNBh*Z9R?9}f^$9g(>o8*YUVr@5 z;+byA#Cx?C1F=w{RpWR>K*wJ9&Wkr#4Y69+^6GbRh6W0pC<>`<$!sJe7j}^M7NqB@ z5c|*xXtmL_?e9NTA>%@8TZ>k90?DlMMGGwoy@oG8^QW*^Bebhg2iFrnw2Bi}4!Opl zbw+5lq@dL%Qr$}HY~@T}9H;CPTDpUybHV|!*Q$wRXwdcR4ZnUpRfkd?N|6iLsJd>b(x4QoV0xh-}bjMPl;#Lu8KVLkvU9-rP{MiDrfp)2dlSJIaNK=+m@&n zP6(B5yqsPd55I`ZHR=snWo~&_$jc$9T}YGZtc@jWPDN(sG85CqoQmP!h3ueY^NvKW zn(PzP?8?z;^qi{X_qWBRq_D=*Rv8t)wh=<=t5t6>%dql~GIwYQ_iuS`h}U%@#Ts|w}F4$2)q{jV11)2fSB5^i=`Wx7ljhP&q*alJFClN*7nk3bnFThW;sW;lv+CcKj9nqao4$>!(CR*YP9C(&jqdQ4LXP53 z=97XS$Cvtzjx-*%EyDqjr;@5IF-e72vMwTERk$>>yjm06YEKpZ1CJ#>_SQBk)vFM= zxLkkBd)yieVtXt*N|`Y;I{i3?rMumg=veQDiYJ7Q&WCPPytcPV z=Rn}8Mw|-Thc^us6t<99z@Nkx7akKiGR*rd>KF%jt`AjbN-(orTNsjFf=p^Gspvuo?# zD0GO9Q42ccpDu0i6E2w@2i~!J(`_+)B`HhQoR&l)qrsdWTbvWCzfWX@d>g+aKDust zlQdn$(mcW-xm4k%#*k-_Ow=V-!SaDvn$}<9cRgg>3fT};RCnQbKu3oC;$-MeXuPS^$0S1{p4bHUDo)HG2AbKC zB6Ge&VzQ=Ut5<7v|GHN~v)FxnW^GHn%n_T1i_ZzHl~fT7@}+9>xL^nPfz9tu%#u_| zFH)h1KJXVLQmh;4PAo3{Lv4f3?yg$Bk*E661L|nOgKe=zL1F~Ig;j0vZTx#gIUf7v z$y0(quK5obuySqa%H;+fN}jd9|^eMt1~(}KR{1k_wy%d&`PswjSFek zxRTJtH#>j#U?CAl>BVZIe+M^7Omw63`!ud7o%H8j5nS&|pcT65t5gZia#=~mn7Lek z&yyIS1L3}|Vm^^ay7N_Q zS-BVImqp)8c3DMMYWNO4867#R|3sXc-$NMjOOU^>=n)dL#U#_L`y{hVUYuF2-Arq) z)3VPU*pW5g>he`*1sZ&o{}QXFc`ZX`oE0ZCk%^yWiYD5Qp8!>m?`}ieczE;}?u4pW zYZuN1{GQ*t?SIbl{PH}O4AuRcsWp@XKK1Rd($kWeJ9EY3J)Bh6F5X0KZ|d3o7c#Mm z6iR=%woa9oT6`ldxa8o_8oX)_EqW%t$v?#kGh8QKPE5mX$HW&Xj41d5nK8iCo^4n2 zC-lr?D98<^^4h|qqKP~llikTC#EgX=R#_3FhZ|{_m3Phpp|5jdT}f&GXIlKFzba5rJX7_GUViIp3`GA^$yZj)^2uQ2b3-G*L;! zW%kP}BK0-XYcji&+0S@s`Oi71*G$mn_A@^e4Tp%4{CPTA$pdz{7LlHV(n6BW~L;{KId(ni<7G@S6wS1;A_7;60`mJ{`H32L9zQ@8<-q~-S zq}E6zWmF5cA)Ge0{7(luEnQ?PKyAX>==1ec#Di65l^Cmqbf3BK6i~vw^PX42 z{>sgZTag_Cv~91V3mQ?O(PHURnhGM*jz;DR&7vTI$SPD;(p38Jdnq>1g~RszIJIO< z1Qk!(<_=FfTl7Hd%8t+E&-tt_)@pCD2gUt#aSrQn%$k7T+s6nN4^$z$?DEMkVdUc-o0d@;Yw7#wB`&KgmsGXu5Cxxo|=DxD3l zNW-R!b>Al1WQR%Wg;hyuZBAS`m56%EqPEd!@21pzj2kdTliuXKY+`yOgo&7_0?teOP0x7pyFqi=GWdL z55cjlzpX~breo4!rFZat5a=Q{G&VY(f5hLQ2F$6@(x0L_wGZh9YkA44hMDHbltnZx zKIeJwo;cd9k97-v_AoVq<-dZZ3Q=Ba=-*iAlY&R+pK!+e?c~ zGZxJ`YJ$yx3Z+Zu5==gBvXX>WJ2j)2OXC%;V6%T|x5Yms87nlEs@GO@Ev%pt7PKhY zT0(@RnD8~LQ0~diPmmJKRBB6UaYN@ zSQAA`-j(`BbxE<)BsK~yukug!>zaI0(=Db)OwUaA_z@-OKLcG`Tg(ON>uOA&-t!7^ zv>{a9WuL-rmyD6BZ_G_kO-~WY4fAT~qEof6qT$fR>SA@4iIFoM)_OpiwI<)x58a76 zj2W`*6ZL^6i2DpHn|Y+MQkov0$ozYMU1qstm+aw-51#-nzc*rgu^6ihGCC5 zM$;?0Zk!@nGIn^~>!X|r<_)s9l|>PYL^+-Gw0EU;_2TS|4PzJaF42HMn-}d_3k`(W z5e2z9ThKZVHOP@rS*2cnKgkZwHg3yUsdI>Udc3cR6^eVcjXBX>B$q!`Tc4&Qp3u8<*2J`n#@H{g3ry^oP2{X` zFwxzL%wKiRe*L#MR?CdRl5xR9b73QXe{E%2s#fvz^9{C2*o86Sid86R^1=d4F&*Zz zToo!zu!@y4Ep$bKO6(x@+N#XvFRwE!(smZ)So|r>%st_P*VvdtV{S1tjYXvo8Kb_A z(yva5ugj#}T9rBtT6<=BwLCY^?5tNT%d4v`etCV4V)J{aV3n#!=3<81iRJ{!8DWJ? zQI%-X(G8Zpq5Gfq*M9@7i!uQaEaC)t4_;m>!Ihiyo@etnt5=F*&sbA)tb)fvbQXLD zBJsTv#@A?A)2lK?3>9UOx1A@zJ6Ti8!77fpnNxE3wWai7IDH%WSVzT(f5TZFuyu`lb2y+dlSsK?Wz-u^bkEqz`k)h#{ zYz{oMZ>_9`R_J%;)xMQ7E3(&rW2JO~X)}J<%tD+Rs8;j}By{?zjaM)xTxCc1$$DA% z8?le6h{h|EOIIT+Oka?+fHGFU01REXfn=8%N{cnGDZjd!I1FRivnU9>gZzTH_ ztSnvPn^-*gzzg>o}c9vJibh|E2+-^TyJ=< zNau`(MHf{0y+#ijKG8OkNw0nPIqYH%XyhRk8yOnG?7U#x8nzz}4XE(&C_b?4tlDLp zvR&4w=pjGGyhe1qgDM*CQ$xd#)Lt1Iwm_8^wmJ>hG*_obLi{}Tko9n6Kt+y?(5RNB zlH#s2IM_ToE~$MOweG*k00NEObd+V5^vD^U_Iy!J<;0QE{L~>2Bgs(Z$7;pkld}H4@!^3(5Z$PB?IYPDrw$ z8Rs>P*6h}`&Cc{PY`^?nbZQ+7!Cl8d_^5dpEa9B}HGtlpMRQs*YJ1 z+UscO-d>yRjY%}Pk{>E#Bg1%rGYpgM1I`iU96oyZh<(^RY8^2HJ~>^ZrMKoJZ-#Qy zC{)?wY9GUtmB%GFG%eNSwzFv|ym)%V84e+97|DfG6%lm)DeI_%W=BS`h-lU-k(;T6 zGMt*Cp3UHKov-WUVBAe6Z?1z>SHIrrlRQxvA%KTfXy6$Cct?~#OW8*bA4LdwKa8eD z&l1yA9A#rOW+PN38`DW=(s@QF2~Jj3pY0d!Sp^c)I{G9DleWpVw&2^xsDyZheI#-? zpn?C1XNWGeXXJF|r>nV3thmw_c&`Lszg}H}-Dxl`&F@zTQAmd19i=0MGlCq}0Cqr2 za2^ru6WPNgIii7n*7v-I8<#P2R(P&SVHy0>v-cgsee=DqKOBn8Pw z_K4JU^3kwK44Ow>v~u(ab~r}u%uP(Al?iiP_P?nMT#Lg@NR3f@abvcMwbLvnw`uH^ zt}z8X3Jiuou#7)XSF_<56Envgm2u<-qHRh z=X*KJ!TBjnDSK2$LfDXg3w{Eg13i<0MwsO|xpCRAM>k_s*$DNYeTElg_fL?CA)|vF z9c?0a>?h>=wIP}Gu)?`RVjMZq=@eQ;FV=v27%SQj50eF@>eA424` zCnw71=wY=*?19kXu*gVOWXLzgDY;?n5XzS3*RIP6f=)IdDsh)$Q@KTkHfot0!}3WN z4y+@>qm`vcrAIrzY(F$`RE3DxFj0X{m>HX3b0t06#2>DHUq97^51p-^ z*)MT*{C0F#e6*hveRNC5MzSTzRI&N;O1Z=iucQSsC9xZkOs4J6hT{lTG=d za~&N_y`SAL0dRchyd}KPqLn`FL7<235Oi{tbTpKRDfW-iOo&u`?_to1I7g$7&#eBn zt5L;YVr*kpZ$XWA5TVgFQe>}O6B+ z;khMMz0mK%GrRE3`DTaF$!RrQMj8~*!*?7TEtOa3Y{Fn;O`=M)aj%81z^zRmfPKXa z@%7d3%84!U!b)G1Lka(O7uP+gxu&^vg?8xYfSs3)DY9}4&u9X!#gbv2<3JVndnN{| zcps=|t4vRKxIH*~DH#ytn7OabD|i}roKuar#lU;<%#lYa0&$U z#iVFsmv2tyi8k(mL_639x)2THaZ?4!Tf~Z3&pa9%Q0-D&b&$x@Z0)i!FAi~L+lSj- zJUZFOk-2yWSoXM_?%DP)vJyxR{I%2l1lBKq$JHl!bOn<=& z?W@>kN_suIg$SJv{J7Hjlhy_~Pu1Rbw)!j(i%%M25pZJI!h;#&2@K0fF`Ec9CV7A= z6`?2KXA=kG{=S@T<6Hwcv%8VmE^(jHp#vR@jLrI-fYBA2tbSDTA~7>U<(!!Lww&E$ zOF2(D=KQ0`qj{OAW~8k=F6Za050W*Qf05P*W9q!f!y7C|T!%%&uXM{Mj)A-b(m>d;l+I)7hI&}gI+MJGMb5DghtQ$R|IdzeJc=SUJ$kqq7m;7><_VXCj7ykDcsxEJ z{wrsVFJDSi;B?=Gn+!u@TTte;5Q}|aCx81mp$#iXsp&!qSa1T1;NZzDOPOVCYzj?w$dL|Ah ziAJrsbOx5e6Grko+9Ow_-O;2M#1YAts8B2g40k~3y;#Y5yP4=Bb za=u##Yh750w47>}9Vjq5c-SS!a|-XvPO8vhc0)h2%qhsKOfYBV+6qrFpfdyRLvrGV z_JyZake8<}%!5o4os6gD#6ohVC(kEYixr2l)@1dvmSdfjG}!XuDW|hpF5jHksbx~DnA4~V#6Kc|c*xIa{DP-b?fl!l#K zTVJ#*Dl(~^Pjk_Zlfn>QE8Zf=aEb4ur6zK?B2OUj+z8$)&qsxT_ax5fper0bzr22F zaCMciCQl~y;3W`1CT64(Y1=e(ya)}RK;Sc;-pTNkgT)g~+I#!Ot89Kc7Nbd*qC z5{mqzTPe~@y4Y0;0*q?ebqfOwkL9F0Dgm-}*R^p>kUKu}#tP)6^jEzm6lt&7ag~$= z=(+PukH+2Sc>z#z&i2RtS^GyKg8(k>`+cAHdA`q&_s7jo|C9EIl>XlZ{vPD@gsIdU zhEj&QOYu>C^Ou!s`LWu|;k&%#f1P_is=D_6BlYo*->ZK4Q=Q6vs7J;B#jmKb-}vY1 zx$$9@|F;wBKfUx#^_Qi8r-TK~l)jR*=?^Kn4Uj^eI>U*0~z0FD;Q&)U- zdFzIL+iZH#{{!XwuPR%qJ)27H@;7aNa&uG3KTD}E9QL1oMX9DM{({==zrw|4b$Jt* zO||8}pdNky7+;MW+gw(Db)c&L6b;mRvNm@ODD{r@wtiE`o^86)t&HazJ!OD<);Rk0emX5=z0b91M!K(l(38kPU90!y`^7}}I!s<))CpOHQqFMZ3MU+Mmn)d3h( z*J7yIe^Q0?*vw5+MrPIJw>Pcp1NHvi0Ec_t;$N-5iCgNw%Ru=3xQy-XTA$7b`;)Ob z>Q;AE{aMXs-OcL!z^;KyD$ugI>j?n>#oWC7M4-lvjQxuG#xb=W-Hz&htl)OH*y1hv z`RS~YR@H$=Y1I5Gf3~|X$wywho@jrXOK&r(Z`Jy_SF~*0_@1);CtzW-zp0J&whGqz z*Ne+C)NKEbQWZ$I$sO}`W2np_X@s=^1&Ub`7CckofW#{<6BujO~r z_8w#wrWts|ZoZ2>s_L(3H>DBe)Bi039OMqh5i$oDsnzU@rK{=zTGW5pWxjwMhME1L z>rLicjxs;qxXPG*e#axX@Jjn#RE;3JeQf|-l2Dh+JtLBKG{e?c^-DeQs=}7A%HOmq zZ_2L$EXk*;`Yuv{d;gCAZ8-@QdcKCc&~!tzj1!{G-2>{p1L64G`e?UOk9IeG^ZssZ z(-|C4>XCs*_`9j!YkFx@rg%ng&CB+vW6cnaJKg}WMiD{HJ>c(px{hkSfO=lo)!Foh zpc=0#wVa4qpbGDLYY5FMx9bIs+W4*+`q{U?FP=$95b6zig`B20WcZ5C-ckm? zZPwm*P&aSO`Z43JCh-xmadX{^ko6F};|iCoXLfJOtNGb43sCGW57JPBWaNS^y}eQLm=Ms%AI2FAc`;is`vs95E@XAXlDrc zSL(i@R70O?7bDiMZWVzIn|G=byVoRC+7}Mh_z6eVp@x-}_4NG%)-#6(jQ<>VB%*W% z2R`z~|H;ZVpV$LNfEThK(iDVwqW#+I3uqpUJyvDAQ+TKNew%-vp`CF2lW0xe{~>47 zAIbOkYaa*|Fk|VNiW>D*pt_iicdBi8)42YI8s(1AkFNhe>fwj=`6Hg!c>dp%*=+hm zHS1CTY009&5C5@Wo$7SRf=!nyeyLl6nOrv>ulVa1$>YAc$*;k?AD=Ex{YEQn{MqT* z=cu?~X$_5xVH>{h*vkAwz&E$eZYmMWybZ7h#g!m9+m6Qh3fI0tTn2?-KJ3tzchj5>6wPOd!?z`3d=wOn z>WaU0Mwy9<{|evQgT9|}jD+vMMeRUR+vWRLyVZd!KE)b+g3H+3o2HAizvifxM6viy zzB_^9OWo>d@!Pk1;Hqs@dmDTQVOOMtK@)_@e`~7Xn3tYKEZQ?T|R1Jxgz5~NQRpOIN-#Q1u#ldr`m7^nF)^Upshf5q?C=)0&oxjXnMA@0U| zd6aZcz4H-dRd(?qaDT!4_HA709TmuEKW6&vd}~5>!8``0 zjAOT!Qbu)8@f!-}I>z)%*rn)z^-=TX4`PW1z6#e7?k0_aPS?g2?YH>5JZWPV%sRD6tz29)A$6pp6_9GlW@co5!;Bav<58y2@D}P7Q?C8M2VrXCwj#aus-maVsWm$x-a z&>y(Re??GaP{Q5aX!lMOIB=KwCF=u`3Hd@V`VQWt?HN4gL(;berNLT0*FE8bX!x9I zehsv%w{~KKpf&rCapNn(j^K@V#hC={h6qyks}QWin%dsCH3i=1LHp_tK7eL})Pz@o z?AZQW+U;-0fRE`IV7_Q>qg9Q!t0)#!kzaUOsk@8CZ$GHk@5FP2uS|{~1H<_Wa$r(o z`VU8~0N&a_tZ_;?U&K{AiZ40k9X!TG77!)Br{nEMum-KH7nwZsPQ0!1v-r;C+Deek z`o%y4_bxmHNkd=%bEUqB)Bs^!$%f2HYcZ$whQAe8O_1ejTD1qr4V^-r@9A98VN0$s zVmC-nOq$3_mV&W(U&t)}iBeyGNfsLFnCOpK`Uba{yU1BYYV)$rW8FHBJsQ%vQ8jCn zFTJc$Y@(-{{?i{q5oW=p`*$*HQ!TSTQOm4`&aBVSk6_vAqs51aPNB~iJC#DJ4@wju z{*q6EKk>X@y(XR%G}9ITI|JIgNRdA{UCZ~P!+VO~l$dEr%mlq?{t3~DzqdV0#&`_v z{pwCOn4WdSH>?hHO`ETqe=7Ddi7~fZVSUS}Y^i~rRzFEk$YPt*#co=WJ*3q=Xyb#e z9)OQKt?Z`a>_Z~KuV4f8^LcYtS_M9kJGm0*I_KkSwRVziKLttU{padgH$XqS*V#Ag z)^mLGdz1|IS^%k}7HIv~^;&>_|Ec=9;JonmRWk;j#5LbgkZnQ@k+$nb-aH4KHH&OCtCUd!@8{He}any18 z3P<(kwgh9Ff^3T36=_$ zGV!ixxEm&iqjar6wHaF~=&DdEH|cpfSNawVr!4_Q)^&qX6^y$>{0u@M8}E(oRfjbK zpIKf@K;+_kf@ciKLO-bKDv> zl!08T14FxRGMQq~umwbU1)bQX>t4yqtNpoLHp%S~7KfDd^>_~445P7n!ieJ#wFEnw z5bQuMC4{ty3gPhHa5RQ?a-alD-ukt;A?WLJf6HXKEZlPPLZNV%=pX=iLhJIEGEoNH zb>wrO6P02;9A!xB0YO;!G-v^97X`sCS4%yDOSTRfEs5)XbzQ;dbFi-C2^3JFTyt-bgu4j6XQ!pJPHd*n@-i)o83-fcP z8;Yu5at9$txtswUR4^}G7`gDd#Eh6rG^xT}*fghT0k5r`icC&=ulv;!z67quZbMw( z%cTNPJC(~ViUt=mkV;uG^^2~X%6a8#Rk}!}Mn^^l2gl-x>*Yl}RjVP|6-~_0#>S-u zBf|Z@zn-Cjlc>oH-fUxz@jN`+vwI|^U%6sr`Es(`DGrzYkY@cYR@JZFqCjKznp zm)BWVsda%{&_f8nO1f@LQ1FYv9QAK0smCF`w57eOUrI)MaYYsCLgRI>cxdq=;cG0N z%g@ZMRjS*`p&Y6jO}Y0i(?>3K;UA;=+ulOVs$oRBqC=B@)x-B>BxDO2iC0+{v0&U0 zCk(m7uHO23CO(+U=L>};Z>>`Pj-68XkESlfp4T0WB`D>lG!9@>6WZZ;RP?71GId83eGf#|2sm_dhsZw6bXU9fHQmJ@! zNHiotHA*aO6}~2x%bu6%sbx8OYn${+*S%z?%#ZeK?-cOLlzVQexVX54Jr3q`>GX5) zFPF>S%h}ZEXeyPACBO~lGI*5Jj?7K?0Q5R-)U!Xhj4S5}qv*BU!98O`xe2dQtzL7# z>=kDhi%VW15BKhM6Xo*FMKSSMDj6Ra-AE9S$~*$Y1?8f%gBwnGrSwc4_kaLAEPYe_{)?j;{1=CTT%v^^I;wX}_pJ z+Xe6D+IL)*bWkU#dkRUn4lBe+YAqmfoP?XXEir7!#$%#ia64fG?w!gNz+GBhE87+I zU>R}OljnWpEf%0f#(kcTvv~=(qoZS|VFPxXSd7Qcd6{rs6RqL%UM3!!MBWg%nhj#M zLUC?>wOqEVs=K_pT3#5cAn(%BY++_f%(uRn&*9?%A+jU<)r^S75_ck}iS|*^1hL`^ z&W^;z;tCR1%H?XgyixwX`=UsEbFR2la?e%i1pQ{Mlr?Im%zs%&E=iuqYMI|)Rm_N7 z@{-Z02rY5wfRtyNY}3Vgk-A!`kdl;B)5gX!p52yV{vfskT>K1Xu zwzr{^mP;ihpDei|`TY_pNCK#2epw4%t%~T^hA?J%)w-!VSO3BlmMrG;*(uSsHA)w$ zi!z^UHQgD|af}{8uSpMIdZXtTFLugor&DW2bUv*WQ)UbPsC2LnN2G_<<<;+CO3}h(8Nbqm+ny;Me+Sp~TtSd%i@pqmMl`4QaDt%`&?|X4UlRDUg9M zRTU_!eRb~4!kyd%K2JAe^l?%8Xd0rA78%8zeOxMC?1@6A9_iz#=xGS5PZw8F6DiZL z@ZT+%<5$3sT*U&_^`$~VSrg>%H2eukh)t)uB_g*H`(KSlj!xd8DGWgmpO7AGb|DP| z)@w@$=gXCf?xC8zA`#{g7s}P|V+ns_g+a(La%s}B`6TFVpg$Xp3{76^y<-Gjm(Wtn zQ7_Xg`1^?igjk%ls9A*ctPm}j=PVyT*za#ApAxDvf?OI?WV5ZQI`YMy$WiZu$mhL_ z-7PUMdq$8uMgJs)!t@-1S1VPSac#RdkULN{ubK(uZ`)X!ot>UdP7rXBT3OlDfW*?a zSlWyChyiX(-fncAFJ<<&L?w(f)7c}sAJr7ax|J%ke=}n~LN5miIp23**K*GiG5>G~ z;R7i%Yp2Y#nI!tP6BE2>Ph`kj=yHTV@bqZ!IWO7MRP!)Ju+eJ4un1oTd&?Yhe6_!t zd|ntzxGBu7tzS5o&$h!!;!~UUsh+09%tDurx!@i(y6(r2M)Z8?VmCpTJAtx` z^Mo0YZKX%8F9B_%1!(fS0tS z;}{(2Zqc#5C3*=C3PloG36X1MG`?UyjO-cnVOB_;YL$X8?G?$cZ8K|?tAnW#@W+@Q znzFwD_T;r_PmM7WBYE}Ks27GS$sQvjYR`+>iR;>P1}j?YTSLTopEc-;RaSO#a%q-6 zcF&jB&pu8cV={tKM(~96q9d3SmRR3i@1?uOMI%bq>VY(a*}D4C{#El)MgS-2ubUB6 z{9A+GbOAAz%L{{2z%c}TC~N+$v0pF4gUiSShcap@KE6gLl6a;nMWX%EMM~7%1`__h``(SPBa2JvBv}%c;FHy6* zsVv?K^>^f7FwbM_3Yqo@OOJ^HC0%ZMZNq(BxFh(4_9sCX3opdF737ac!IjGH-Wo%3 zSxL3`rN_0q61lKvUHD*3hL~Ta$G_ef!Kh@vteLIhdl#cJ3oS)^ z>iCD7V5jRC2V!0>9v{kP^TfxpWDG5TJw|qrM9O7?vj4t2o+qd)r!ZH3)5QdVQMEsn zPCulK7%p^1343Clb@UjTStRX=d%4k+gdK7cH1xNISZ0&kwL-sm*BA7NAOKI)HOf=JwJ<;l`d&#fJE-^p(MGBAf#9a9` z$V1tOUO-zg64Y~2CHjs%p<<*;9zU7jS(&N)> z+d>;}?3?Yz^Ai0D5ws4tfV7_Z6+I`i_vLrQqO7VBeoTrc)tSm>HA#?9+p><_EsAg*p}HWC*JOrrwHUw-(aA~$*yYs}QtEvbCx{!?YZ6 zbKG;i@-3$4f=i2Ek46cF7sFe1sM(Sf}9iFRtFa zNtatLzB!I2{+BCt9oXsIZylXP!Kw?NjNd}Pybjm$g~6N!V8q36{+kciq}|sp5)If!qwd&P`uBbZ^IQ@G^v#}_m<-Az$4r&~FccR<->f%Bu_Xeo0c|&xdI^Y6= zN^e_kQ4zy?r>|GubD3u$YbuwCWzcP%$aU01k!V7aJ-JP8nV4qUcI#Y?2j_Q7RE4@5 z8>=^0Zr&7OzgV1|EzXlW&*cIs)sdcx$>=3)#A<8U;2tt!x)e0JL{dqZYZYosBu$zx zYDxE$%WDjOd2W7LWL;uMS%p^0a3Y^&@kn*#am2lW1%v7iW#-zA;oZ zF}+&e;?SRFtn7T&ZDm8RoA!zdu5kw7%d6HrpDKQGT;^Hr>4~3aO-A$@Jp-afZ9%Va zHhc=j!-CcFRqY3O*zViRYFnOPo?nHwTSIFKriI9%f0IC3y;hJr-PJ9Mg}V*Zx?Y`s z#-d8L@JDOwlyk5&$=l%U)x`K_zCrn_wGD$`C&z@jRtk)6a6kU1GOhtrSEv zMsDtn$hs7fBy)v!0j5LSLkd)z2qohStgWrCtuaqECGIB88+gJ2zv90;#L`nL`+I=a zSX7sDk7zL)ZxPhO^mm8!s){6pg-79gKw>q!9%XAIzzmWeyWeDHC%;#d69km>?=x(1 zc1Q5adffQs5gGQx^ui;)�_zDl2qYX=COOM(}-?Ih=gj{pPtmAW7AP;$wQP7mUM% zw#Cd(2}WU#@|xINsl0Z+Lt+JUrbszZk$P?6DgIPcr;iy53@#%C!KXnGN%Y7v?#Ku; zm}~53%G{lb`UVGW1%p!-y&EbCJBK{eLQ50Q^A<-kgfPiHR6 z^m(oPeRd^~2uW;app33vFwqP;6U;z{i8h1xRr|X`j1o-7$mwN$$aHs0JW(11aH8O{ zgn$oO<&3WOMd!?&u^w}2yBa9lYxsxuXXYC=OsRt2US$fCPU%$HQ^!1jElWd!dG)+s zC7`TodomaF0~K;Y6;^Bn8?2L}h>k?kN2}aK_o}PHr7UFU$t(_Y#&=ylUACAZJiXslD!)l^WfO%c;;c5pU*D+ z1?o|Iumst9dC3E8PPNrm4urPa9`@BMdfbtPL^eC5$680bmn?N3Xzq*E^;xE5Np1va zO~DtNxW6o`wo8jki;J_w=!mR135oQ4VN1`c+UaD=&7~8V+7Z;hlQoFwhet=JhAQP1 zvQVhR(3#K?H_bJ3El}pKtoH<#yt$bf6(}fYRu;3U?kt(n@4-4aH$f+z9eUR7(feMY z?l*d^u~g;}k#wSf#mgJkO> zFV=!TG@5o_EUy$;t8i~rHas$sr#i(N%kt0jw1_f>yxdcm)|pC|ay8BF*=G5Q;D$$L zqbNXQze7}TT2rZ^%EoMdDnFH|R&NI8Y|pw0dT7pD^k!JSvGc)#3NUiCE$c`~+L5^; z6&-Wx6q`kQmlCXQM>IluaWs1nC0GAcia%U)I;v9oDxsJu~Nt?TMJe`B#wh|HKvrWXKbg4Lr?PPK~eWMOV~ ztv=GWh09W{tW_^YyG1H_bu=Zms%ec2h=f3*tcgq>5tY?c}~XN_YI zTLvmvjI(Vkp*dSwKxcKVV9VJn<;5wPC%6?xi}`{Dd(kdfdDhHwHtRNOPc}O>B`d#o z*t0cxePeZHwQ?)kQ%5=+b;}#GRPCAb<#kr{Ccr98F%%=S0@@jE*o+Y5}2GX9E==JqklELqv*Fq{QE$fTzXp5o@EPF)lrbrS$z+YJ+ zUbQx;I(`4O-vnz;Pkn_G_}0D5Tdpq^NOkV>?D0wciRsd;$kjE*oN&w>3yi3s)G~!> z&WEm;E5vH>wi2r>h2>;2)bQ1yEJ`irWWIV5Gswi7Sv|24?Pq~xEl#zwt9W6U0h3}l zZ4sQO-soUPken|Treslc2kijULD}O-Vbi5-N}7x^MDT2(STJRcuuCyAI4lWS#=5Ek zD{BAh{QOFh8t}E>Tq#^-2{hVMk0k8&vLP>3OyI&(8!z)V!m9h|9$wandBGg9PN`50 zYlYAhS|OIU%Q%+`&$0s)*Eqz^-7=qKS0t4>S^nFpvET?3IYevKy0S;iQ`WHBr&Fkq zf;c^2Tv?gN8C1u7rFx-Qc=7-XV~n#N-8)#B@iK!Wsbm5pC_zButr&yRo!%Q+%w zhb|0X7#=>=KYXeV$n0TtMcMOeAAp7FHLB9t&WJ0^M-9Xd(O&#Rr&1@cuTPCA#uxx~ zWKeaCScB>acxTV{_n$g7nx4>0;;XAdJ_Ll*?f;=tbzhcB6fMfA$>F<=F0^>2Wh9wc z`|fk--s}gnogL?q!4a&=%er6=o5R-GK)(tOk7DCxd(|phE1Z1NsEj-_#+rm^vyOUD z>#|1;4nJIed2AS!@gKM$wwVV9FN~0${P? zze)b7DYRZ~9B%58JqC5keSTwV49xyvLAF62Jax()9=@Qgldb*gxM0f4;5>>X%&hRn zTGg8W9t%#gARq0lBcjh4+0u#qOnF80*{>qQfC}na(XMlL_^f;KWdB)EL!#ES>?N?S z2#@v^rdXX?^Q(Z0QqS}>s-jNT_j4>I{1j9g8^OZh2C+1-_DQqfJnQtUz={68{yyok zU3>~giI4@@z8~X{v+Px=LQknRFX|eOs&%)~E9-_Vbo?fK8n*k*Q}Wu~AMC?A58{I3 zz!dTm<2d4MAv*<4%kK*zQDde{#th1Su@3Xtmgpa^PmO5?f->CRZ}!<}9 zL#tG78kii5aD~~z6haaH*IACLTcuG;i&a=(Z;4(1?v!vmfJ|-u!4t|leu6(DTib{* zr^wEroI)t5{drlrU0t1#6=Y5E&N|w`h%np{?=FpvU<&b&)_%KB*~d>D@3W38`$S)# zNZ5JmR84J!xHL(tV2!IiEFi2rE`D9NNFBAkZV^VFAF+o;Li1FxAK|owDk9kYrV(bDG~|S5~I~YmbpM*>8Y_(e5qH@#XxU2Smw*@RfwOB2M`viM+926 ziuC>ceaDZV0KfGFCLlmTb!rP%28h!sb%6D=`PKiTy}no0jt`dSLrh;J9-7`uh8c&r&y8>|#nr=+?UcX;H`v!m+EEkxj;)&N^~OFCzK;n_tjLLFIW@mljHjQ551*Wl3HDbtL!Ukjx4fFR7c+} z8)|3RBoh8f91M(LA;~2DCKf~&&IwV4oNPi|*)y|J=<8rg>w--nS>Nk64zOdfw}Hvt zJZD)jq3nwE1x}eG<_Hx~NV0**3ThAy<80W=NssH@+%ZOUh}6u|_X`>pFEQE(u;GTR zoqKWUUTwTH95e18Mh^CW5o-!P21iD)VLy5Z^!J|~=BH8Ru+%U?()+uD&pGxKPQ&cVt z3fGyQ-}p{5pA!eTU$nl3Uu zJ4>iQNN5u{9z=H43iSBI6c>jXM<7+0U%Mqc%k8X;m!b~2qI8GsEo2`jf|cWP+S=(u z^b}PwxuCT$#i1aP9Zxs=%sw)k16MfQm6i%gKBv*k(;6FuGu>ffc0(_1oD^bH1qQNe z$33CDB>a+V0?Z_53nKJMtrznIQOgmfQ6vg-L~fk;qtzccHM!X@ySP`p=JW@#9bsax zoLxB7FVMswYL{Yx9Yd%haSypgYVff1*ofq7KCuVz4LSSX#y~@=_XA5dmm&^jh`?z1(^}K$Lt;6aXcPBGFIr*;i8(iQwbwyn_Hf~byxNR*4irHW zDI-7*-hFDcP+Xz*XayP@4iBF=VG~u49LF)GvgnZf4TnVH?>cf4MtE213A2U$uWsWy zN43NxLVZu*XMvrUnkFK}hZdQ1h#o|0WDZgaN`w-|JtHTA+JteSUh-Hi+>!R^%(Zw} zsG(8qyGF*RsnlD+tjkJ13>^71p<41*Py+X`R2w1qhQPPXHLY&|= zAZKV=E_u%aviPJSwg4%D6=P%z!j24QV)|QhmW~a~4C$4#X)+ou$Ap)ZGVrvV zfolH{K|;b8){$yJ5c=v7f`IdKr<}kN59>P*Ycx%AP)e!`es5#)D<>Lt6bK%- zYwg7{g_pZKMF!oTgE%`fG^II3z||g3q?rd~=0^RYM?p@gX+n=7|KL99|8Z}DEW^pY zhAzo3`M54__}%_-(gvKhPMnY;PuepA7>p9~59!l%A_3Ikd4Yx&3^`7y5%w#yl}al_ zB?nh=UENx{))db%*5qfQ(c{$EPHVo#8AFepe6tLri9|_-sq0nxZqqTakl~=SJ|QS) zD6&$P)~iXUjUb!G1Zc0FGxO1&@P5%A7~&~}i_ugz9*M@~q$L`Z_SfL?=|+3T^X#NI zbw*gixkZj}_c-Ccc3sm_qzqHNx*W`A;fOn&So$WdGmVPVF@`2Hlh;de&BNLW5jm)@ z!pHH2edz7iIyw3uld{$2khSnt&NyDbmLPrU>XMm&6U!}JDw8Gg{tm<7BtFN`OEPPb zs=zY3`Vwy>5fxce{1%nd`Vmfo=h!1ixQ$u#iI(K~ zitlCJSPam(9JQOA@t`E9kim7jIKG~BF`Ut2#W?LkXPg1$xH9trPaTkFEZjJ|Zt|c2 z2d@`cca@nhFZP{2@w)%MJhUKZ>v>{fh8CaUG(bb*q1<9F9(KY;3p<|rz_>i>!7)Zo z4DOR%6KR=Bb9(!I+0PSPR!*oomO07hv9@Q+^Z^pKe3ynN_7Ck(Fb-B~H(nU$m0tLvQ2w>X0@C&o``E5Yyd zgn-3Fq;OYU;PRYqrl}C67rY5t1+9Dz6)!7o@ACg;6G^~gh=DnJIi(MtKJl#|zz{&q z-fj>HS3-9=*ewt2boKVqz2&k3$ARh0Ua$l&gjexZpRu>Qx_ZNw!?`%<2BAD}G0BL- zQZXDBrSXJ-*WkN>p?Z7eWWFmBVP`>nk67Ho*h)N-A#2)jw{0J!*WxWE_46V44=3;7 zxbPL5#Mz^j`-DP*)1^0>z##Zxi(1dmyyC*@Zg zi_pfbwK}ADJb*(}i^w_whk4FIIMS{6Kcaj?HIp+lo;+p6^9a(e-jX!q=x~Jh5_V_@ zxsOUz Date: Wed, 23 Mar 2011 11:56:35 +0000 Subject: [PATCH 59/90] Paolo Devoti: Some Italian fixes. See issue #5847 for more details. svn path=/trunk/; revision=51122 --- reactos/base/applications/games/winmine/lang/it-IT.rc | 2 +- reactos/base/applications/network/ping/lang/it-IT.rc | 4 ++-- reactos/dll/cpl/desk/lang/it-IT.rc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/base/applications/games/winmine/lang/it-IT.rc b/reactos/base/applications/games/winmine/lang/it-IT.rc index 9bf28fca948..9c3643d2e77 100644 --- a/reactos/base/applications/games/winmine/lang/it-IT.rc +++ b/reactos/base/applications/games/winmine/lang/it-IT.rc @@ -29,7 +29,7 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE BEGIN - IDS_APPNAME, "WineMine" + IDS_APPNAME, "WinMine" IDS_NOBODY, "Nessuno" IDS_ABOUT, "Copyright 2000 Joshua Thielen" END diff --git a/reactos/base/applications/network/ping/lang/it-IT.rc b/reactos/base/applications/network/ping/lang/it-IT.rc index 211918a158b..f23a0f8f1ca 100644 --- a/reactos/base/applications/network/ping/lang/it-IT.rc +++ b/reactos/base/applications/network/ping/lang/it-IT.rc @@ -16,7 +16,7 @@ Opzioni:\n\ IDS_APPROXIMATE_ROUND_TRIP "Tempo approssimato di andata e ritorno in milli-secondi:\n\0" IDS_MIN_MAX_AVERAGE " Minimo = %1, Massimo = %2, Media = %3\n\0" IDS_NOT_ENOUGH_RESOURCES "Risorse disponibili insufficienti.\n\0" - IDS_UNKNOWN_HOST "Host sconosciuto%1.\n\0" + IDS_UNKNOWN_HOST "Host sconosciuto %1.\n\0" IDS_SETSOCKOPT_FAILED "setsockopt fallito (%1!d!).\n\0" IDS_COULD_NOT_CREATE_SOCKET "Impossibile creare il socket (#%1!d!).\n\0" IDS_COULD_NOT_INIT_WINSOCK "Impossibile inizializzare winsock dll.\n\0" @@ -24,7 +24,7 @@ Opzioni:\n\ IDS_BAD_PARAMETER "Parametro errato %1.\n\0" IDS_BAD_OPTION_FORMAT "Formato opzione errato %1.\n\0" IDS_BAD_OPTION "Opzione errata %1.\n\0" - IDS_BAD_VALUE_OPTION_L "Valore errato per il parametro -l, l'intervallo valido č tra 0 to %1!d!.\n\0" + IDS_BAD_VALUE_OPTION_L "Valore errato per il parametro -l, č valido un valore tra 0 to %1!d!.\n\0" IDS_REPLY_FROM "Risposta da %1: bytes=%2!d! time%3%4 TTL=%5!d!\n\0" IDS_DEST_UNREACHABLE "Host destinazione irraggiungibile.\n\0" IDS_COULD_NOT_TRANSMIT "Impossibile trasmettere dati (%1!d!).\n\0" diff --git a/reactos/dll/cpl/desk/lang/it-IT.rc b/reactos/dll/cpl/desk/lang/it-IT.rc index 3ffdf49c497..30af0cd3ded 100644 --- a/reactos/dll/cpl/desk/lang/it-IT.rc +++ b/reactos/dll/cpl/desk/lang/it-IT.rc @@ -260,6 +260,6 @@ END STRINGTABLE DISCARDABLE BEGIN IDS_DISPLAY_SETTINGS "Impostazioni del monitor" - IDS_APPLY_FAILED "Impossibile applicare le uove impostazioni..." + IDS_APPLY_FAILED "Impossibile applicare le nuove impostazioni..." IDS_APPLY_NEEDS_RESTART "E' necessario riavviare il computer per applicare le modifiche." END From 17d6f165a78e1d9ada25273eaa8fd6e194dda1f8 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 23 Mar 2011 12:25:53 +0000 Subject: [PATCH 60/90] [NTDLL/LDR] - Fix a few bugs (wrong variable usage, wrong variable initialization) which led to incorrect snapping of import address table. - Wrap LdrpSnapThunk() invocations into SEH. svn path=/trunk/; revision=51123 --- reactos/dll/ntdll/ldr/ldrpe.c | 68 +++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/reactos/dll/ntdll/ldr/ldrpe.c b/reactos/dll/ntdll/ldr/ldrpe.c index ddcaf617e50..730d260d836 100644 --- a/reactos/dll/ntdll/ldr/ldrpe.c +++ b/reactos/dll/ntdll/ldr/ldrpe.c @@ -44,7 +44,7 @@ LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, ULONG IatSize; //PPEB Peb = NtCurrentPeb(); NTSTATUS Status; - PIMAGE_THUNK_DATA Thunk, OriginalThunk, FirstThunk; + PIMAGE_THUNK_DATA OriginalThunk, FirstThunk; LPSTR ImportName; ULONG ForwarderChain; PIMAGE_NT_HEADERS NtHeader; @@ -52,6 +52,8 @@ LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, ULONG i, Rva; ULONG OldProtect; + DPRINT("LdrpSnapIAT(%wZ %wZ %p %d)\n", &ExportLdrEntry->BaseDllName, &ImportLdrEntry->BaseDllName, IatEntry, EntriesValid); + /* Get export directory */ ExportDirectory = RtlImageDirectoryEntryToData(ExportLdrEntry->DllBase, TRUE, @@ -101,13 +103,13 @@ LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, { IatSize = SectionHeader->SizeOfRawData; } - + /* Found it, get out */ break; } /* No match, move to the next section */ - ++SectionHeader; + SectionHeader++; } } @@ -154,17 +156,24 @@ LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, ForwarderChain = (ULONG)FirstThunk->u1.Ordinal; /* Snap the thunk */ - Status = LdrpSnapThunk(ExportLdrEntry->DllBase, - ImportLdrEntry->DllBase, - OriginalThunk, - FirstThunk, - ExportDirectory, - ExportSize, - TRUE, - ImportName); + _SEH2_TRY + { + Status = LdrpSnapThunk(ExportLdrEntry->DllBase, + ImportLdrEntry->DllBase, + OriginalThunk, + FirstThunk, + ExportDirectory, + ExportSize, + TRUE, + ImportName); - /* Move to the next thunk */ - FirstThunk++; + /* Move to the next thunk */ + FirstThunk++; + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + Status = _SEH2_GetExceptionCode(); + } _SEH2_END; /* If we messed up, exit */ if (!NT_SUCCESS(Status)) break; @@ -184,7 +193,7 @@ LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, if ((IatEntry->Characteristics < NtHeader->OptionalHeader.SizeOfHeaders) || (IatEntry->Characteristics >= NtHeader->OptionalHeader.SizeOfImage)) { - /* Reuse it, this is a strange linked file */ + /* Refuse it, this is a strange linked file */ OriginalThunk = FirstThunk; } else @@ -203,18 +212,25 @@ LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, while (OriginalThunk->u1.AddressOfData) { /* Snap the Thunk */ - Status = LdrpSnapThunk(ExportLdrEntry->DllBase, - ImportLdrEntry->DllBase, - OriginalThunk, - FirstThunk, - ExportDirectory, - ExportSize, - TRUE, - ImportName); + _SEH2_TRY + { + Status = LdrpSnapThunk(ExportLdrEntry->DllBase, + ImportLdrEntry->DllBase, + OriginalThunk, + FirstThunk, + ExportDirectory, + ExportSize, + TRUE, + ImportName); - /* Next thunks */ - OriginalThunk++; - Thunk++; + /* Next thunks */ + OriginalThunk++; + FirstThunk++; + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + Status = _SEH2_GetExceptionCode(); + } _SEH2_END; /* If we failed the snap, break out */ if (!NT_SUCCESS(Status)) break; @@ -498,7 +514,7 @@ LdrpHandleOneOldFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL, //ULONG IatSize, i; LPSTR ImportName; NTSTATUS Status; - BOOLEAN AlreadyLoaded = FALSE, StaticEntriesValid = FALSE, SkipSnap = TRUE; + BOOLEAN AlreadyLoaded = FALSE, StaticEntriesValid = FALSE, SkipSnap = FALSE; PLDR_DATA_TABLE_ENTRY DllLdrEntry; PIMAGE_THUNK_DATA FirstThunk; PPEB Peb = NtCurrentPeb(); From aeddc6ac0c936e4c56b85cffa944851641e0bdb8 Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Wed, 23 Mar 2011 14:39:39 +0000 Subject: [PATCH 61/90] Jeisson Toscano: Some Spanish translation updates plus some corrections added by elhoir and me. Bugs: 5891, 5892 and 5897. See issue #5891 for more details. svn path=/trunk/; revision=51124 --- reactos/base/applications/cacls/lang/es-ES.rc | 74 +++++++++++++++++++ reactos/base/applications/cacls/rsrc.rc | 1 + .../applications/games/winmine/lang/es-ES.rc | 2 +- .../applications/network/ipconfig/ipconfig.rc | 1 + .../network/ipconfig/lang/es-ES.rc | 65 ++++++++++++++++ .../base/applications/shutdown/lang/es-ES.rc | 14 ++++ reactos/base/applications/shutdown/rsrc.rc | 1 + 7 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 reactos/base/applications/cacls/lang/es-ES.rc create mode 100644 reactos/base/applications/network/ipconfig/lang/es-ES.rc create mode 100644 reactos/base/applications/shutdown/lang/es-ES.rc diff --git a/reactos/base/applications/cacls/lang/es-ES.rc b/reactos/base/applications/cacls/lang/es-ES.rc new file mode 100644 index 00000000000..37ff0bb2763 --- /dev/null +++ b/reactos/base/applications/cacls/lang/es-ES.rc @@ -0,0 +1,74 @@ +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +BEGIN + +IDS_HELP, "Muestra o modifica la lista de control de accesos (ACLs) de los archivos\n\n\ +CACLS archivo [/T] [/E] [/C] [/G user:perm [...]] [/R usuario [...]]\n\ + [/P user:perm [...]] [/D usuario [...]]\n\ + archivo Mostrar ACLs.\n\ + /T Cambia ACLs de los archivos especificados en\n\ + el directorio actual y todos sus subdirectorios.\n\ + /E Edita la ACL en lugar de reemplazarla.\n\ + /C Continúa en caso de errores de acceso.\n\ + /G user:perm Da los derechos de acceso al usuario especificado.\n\ + Perm puede ser: R Lectura\n\ + W Escritura\n\ + C Modificación (Escritura)\n\ + F Control total\n\ + /R usuario Revoca los derechos de acceso al usuario especificado (unicamente válido con /E).\n\ + /P user:perm Reemplaza los derechos de acceso del usuario especificado.\n\ + Perm puede ser: N Nada\n\ + R Lectura\n\ + W Escritura\n\ + C Modificación (Escritura)\n\ + F Control total\n\ + /D usuario Revoca el acceso al usuario especificado.\n\ +Es posible usar comodines para especificar más de un archivo por comando.\n\ +Se puede especificar más de un usuario por comando.\n\n\ +Abreviaciones:\n\ + CI - Herencia del contenedor.\n\ + ACE será heredado a los directorios.\n\ + OI - Herencia del objeto.\n\ + ACE sera heredado a los archivos.\n\ + IO - Herencia sola.\n\ + ACE no se aplicará al archivo/directorio actual.\n" + +IDS_ABBR_CI, "(CI)" +IDS_ABBR_OI, "(OI)" +IDS_ABBR_IO, "(IO)" +IDS_ABBR_FULL, "F" +IDS_ABBR_READ, "R" +IDS_ABBR_WRITE, "W" +IDS_ABBR_CHANGE, "C" +IDS_ABBR_NONE, "N" +IDS_ALLOW, "" +IDS_DENY, "(DENEGA)" +IDS_SPECIAL_ACCESS, "(acceso especial:)" +IDS_GENERIC_READ, "GENERIC_READ" +IDS_GENERIC_WRITE, "GENERIC_WRITE" +IDS_GENERIC_EXECUTE, "GENERIC_EXECUTE" +IDS_GENERIC_ALL, "GENERIC_ALL" +IDS_FILE_GENERIC_EXECUTE, "FILE_GENERIC_EXECUTE" +IDS_FILE_GENERIC_READ, "FILE_GENERIC_READ" +IDS_FILE_GENERIC_WRITE, "FILE_GENERIC_WRITE" +IDS_FILE_READ_DATA, "FILE_READ_DATA" +IDS_FILE_WRITE_DATA, "FILE_WRITE_DATA" +IDS_FILE_APPEND_DATA, "FILE_APPEND_DATA" +IDS_FILE_READ_EA, "FILE_READ_EA" +IDS_FILE_WRITE_EA, "FILE_WRITE_EA" +IDS_FILE_EXECUTE, "FILE_EXECUTE" +IDS_FILE_DELETE_CHILD, "FILE_DELETE_CHILD" +IDS_FILE_READ_ATTRIBUTES, "FILE_READ_ATTRIBUTES" +IDS_FILE_WRITE_ATTRIBUTES, "FILE_WRITE_ATTRIBUTES" +IDS_MAXIMUM_ALLOWED, "MAXIMUM_ALLOWED" +IDS_ACCESS_SYSTEM_SECURITY, "ACCESS_SYSTEM_SECURITY" +IDS_SPECIFIC_RIGHTS_ALL, "SPECIFIC_RIGHTS_ALL" +IDS_STANDARD_RIGHTS_REQUIRED, "STANDARD_RIGHTS_REQUIRED" +IDS_SYNCHRONIZE, "SYNCHRONIZE" +IDS_WRITE_OWNER, "WRITE_OWNER" +IDS_WRITE_DAC, "WRITE_DAC" +IDS_READ_CONTROL, "READ_CONTROL" +IDS_DELETE, "DELETE" +IDS_STANDARD_RIGHTS_ALL, "STANDARD_RIGHTS_ALL" +END diff --git a/reactos/base/applications/cacls/rsrc.rc b/reactos/base/applications/cacls/rsrc.rc index b392e1ea202..2585185bb37 100644 --- a/reactos/base/applications/cacls/rsrc.rc +++ b/reactos/base/applications/cacls/rsrc.rc @@ -2,6 +2,7 @@ #include "resource.h" #include "lang/bg-BG.rc" +#include "lang/es-ES.rc" #include "lang/ca-ES.rc" #include "lang/cs-CZ.rc" #include "lang/da-DA.rc" diff --git a/reactos/base/applications/games/winmine/lang/es-ES.rc b/reactos/base/applications/games/winmine/lang/es-ES.rc index a6cca74a676..82bde4e757c 100644 --- a/reactos/base/applications/games/winmine/lang/es-ES.rc +++ b/reactos/base/applications/games/winmine/lang/es-ES.rc @@ -24,7 +24,7 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE BEGIN - IDS_APPNAME, "WineMine" + IDS_APPNAME, "WinMine" IDS_NOBODY, "Nadie" IDS_ABOUT, "Copyright 2000 Joshua Thielen" END diff --git a/reactos/base/applications/network/ipconfig/ipconfig.rc b/reactos/base/applications/network/ipconfig/ipconfig.rc index d471073b6f7..7627a1de6a2 100644 --- a/reactos/base/applications/network/ipconfig/ipconfig.rc +++ b/reactos/base/applications/network/ipconfig/ipconfig.rc @@ -11,6 +11,7 @@ #include "lang/bg-BG.rc" #include "lang/de-DE.rc" #include "lang/en-US.rc" +#include "lang/es-ES.rc" #include "lang/fr-FR.rc" #include "lang/id-ID.rc" #include "lang/it-IT.rc" diff --git a/reactos/base/applications/network/ipconfig/lang/es-ES.rc b/reactos/base/applications/network/ipconfig/lang/es-ES.rc new file mode 100644 index 00000000000..969900d3826 --- /dev/null +++ b/reactos/base/applications/network/ipconfig/lang/es-ES.rc @@ -0,0 +1,65 @@ +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +BEGIN + IDS_BCAST "Broadcast" + IDS_P2P "Peer To Peer" + IDS_MIXED "Mixto" + IDS_HYBRID "Híbrido" + IDS_UNKNOWN "Deconocido" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_OTHER "Otro Tipo de Adaptador" + IDS_ETH "Adaptador Ethernet" + IDS_TOKEN "Adaptador Token Ring" + IDS_FDDI "Adaptador FDDI" + IDS_PPP "Adaptador PPP" + IDS_LOOP "Adaptador Loopback" + IDS_SLIP "Adaptador SLIP" +END + +STRINGTABLE DISCARDABLE +BEGIN +/* Please keep the spacing/formatting as per En.rc when translating */ + IDS_USAGE + "\nUSO:\n \ + ipconfig [/? | /all | /renew [adaptador] | /release [adaptador] |\n \ + /flushdns | /displaydns | /registerdns |\n \ + /showclassid adaptador |\n \ + /setclassid adaptador [classid] ]\n \ + \n \ + En la cual\n \ + adaptador Nombre de la conexión\n \ + (caracteres especiales * and ? autorizados, ver ejemplos)\n \ + \n \ + Optiones:\n \ + /? Muestra este mensaje de ayuda\n \ + /all Muestra todas las informaciones de configuración.\n \ + /release Libera la dirección IP para el adaptador especificado.\n \ + /renew Renueva la dirección IP para el adaptador especificado.\n \ + /flushdns Purga la cache de Resolución DNS.\n \ + /registerdns Actualiza todas las concesiones DHCP y registra de nuevo nombres DNS.\n \ + /displaydns Muestra el contenido del cache de Resolución DNS.\n \ + /showclassid Muestra todos los class IDs dhcp concedidos al adaptador.\n \ + /setclassid Modifica el class id dhcp.\n \ + \n \ + Generalmente se muestra solamente la dirección IP, la máscara de red y\n \ + la puerta de enlace predefinidas de cada adaptador relacionado a TCP/IP.\n \ + \n \ + Para los parámetros Release y Renew, si no se especifica un adaptador, entonces la(s) dirección(es)\n \ + IP asignada(s) para todos los adaptadores relacionados a TCP/IP serán liberadas o renovadas.\n \ + \n \ + Para Setclassid, si no se especifica algún ClassId, este será removido.\n \ + \n \ + Ejemplos:\n \ + > ipconfig ... Muestra informaciones.\n \ + > ipconfig /all ... Muestra informaciones detalladas\n \ + > ipconfig /renew ... Renueva todos los adaptadores\n \ + > ipconfig /renew EL* ... Renueva todas las direcciones IP de los adaptadores\n \ + cuyo nombre comienza con EL\n \ + > ipconfig /release *Con* ... Libera todas las conexiones concernidas,\n \ + ej. ""Conexión al area local 1"" o\n \ + ""Conexión al area local 2""\n" +END diff --git a/reactos/base/applications/shutdown/lang/es-ES.rc b/reactos/base/applications/shutdown/lang/es-ES.rc new file mode 100644 index 00000000000..47a5f45296e --- /dev/null +++ b/reactos/base/applications/shutdown/lang/es-ES.rc @@ -0,0 +1,14 @@ +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +BEGIN + +IDS_USAGE, "Utilización: shutdown [-?] [-l | -s | -r] [-f]\n\n\ + Ningún argumento o -?\tMuestra este mensaje\n\ + -l\t\t\tDesconectarse\n\ + -s\t\t\tApagar el equipo\n\ + -r\t\t\tApagar y reiniciar el equipo\n\ + -f\t\t\tObliga las aplicaciones en curso de ejecución a apagarse sin advertencias\n\ + \t\t\tSi no especifica algún otro parámetro, esta opción\n\ + \t\t\tprovocará también una desconexión" +END diff --git a/reactos/base/applications/shutdown/rsrc.rc b/reactos/base/applications/shutdown/rsrc.rc index eda9b52beb0..c06b62f28f9 100644 --- a/reactos/base/applications/shutdown/rsrc.rc +++ b/reactos/base/applications/shutdown/rsrc.rc @@ -6,6 +6,7 @@ #include "lang/el-GR.rc" #include "lang/en-US.rc" #include "lang/fr-FR.rc" +#include "lang/es-ES.rc" #include "lang/it-IT.rc" #include "lang/ja-JP.rc" #include "lang/ko-KR.rc" From 2165af88182a807103ce04393872c6e2dd196461 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Wed, 23 Mar 2011 15:33:13 +0000 Subject: [PATCH 62/90] [WIN32K] Check for failed allocations when creating window See issue #6021 for more details. svn path=/trunk/; revision=51125 --- .../subsystems/win32/win32k/ntuser/window.c | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 4d80898aa0a..72d232b5393 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -1940,7 +1940,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, DWORD dwShowMode = SW_SHOW; CREATESTRUCTW *pCsw = NULL; PVOID pszClass = NULL, pszName = NULL; - DECLARE_RETURN(PWND); + PWND ret = NULL; /* Get the current window station and reference it */ pti = GetW32ThreadInfo(); @@ -1960,7 +1960,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if(!Class) { DPRINT1("Failed to find class %wZ\n", ClassName); - RETURN(NULL); + goto cleanup; } /* Now find the parent and the owner window */ @@ -1982,7 +1982,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, { DPRINT1("Cannot create a child window without a parrent!\n"); EngSetLastError(ERROR_TLW_WITH_WSCHILD); - RETURN(NULL); /* WS_CHILD needs a parent, but WS_POPUP doesn't */ + goto cleanup; /* WS_CHILD needs a parent, but WS_POPUP doesn't */ } ParentWindow = hWndParent ? UserGetWindowObject(hWndParent): NULL; @@ -2008,7 +2008,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if(!Window) { DPRINT1("IntCreateWindow failed!\n"); - RETURN(0); + goto cleanup; } hWnd = UserHMGetHandle(Window); @@ -2023,6 +2023,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, // Allocate the calling structures Justin Case this goes Global. pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK); pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK); + if (!pCsw || !pCbtCreate) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } /* Fill the new CREATESTRUCTW */ RtlCopyMemory(pCsw, Cs, sizeof(CREATESTRUCTW)); @@ -2036,6 +2041,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, ANSI_STRING AnsiString; AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(ClassName)+sizeof(CHAR); pszClass = UserHeapAlloc(AnsiString.MaximumLength); + if (!pszClass) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } RtlZeroMemory(pszClass, AnsiString.MaximumLength); AnsiString.Buffer = (PCHAR)pszClass; RtlUnicodeStringToAnsiString(&AnsiString, ClassName, FALSE); @@ -2045,11 +2055,16 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, UNICODE_STRING UnicodeString; UnicodeString.MaximumLength = ClassName->Length + sizeof(UNICODE_NULL); pszClass = UserHeapAlloc(UnicodeString.MaximumLength); + if (!pszClass) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } RtlZeroMemory(pszClass, UnicodeString.MaximumLength); UnicodeString.Buffer = (PWSTR)pszClass; RtlCopyUnicodeString(&UnicodeString, ClassName); } - if (pszClass) pCsw->lpszClass = UserHeapAddressToUser(pszClass); + pCsw->lpszClass = UserHeapAddressToUser(pszClass); } if (WindowName->Length) { @@ -2061,8 +2076,13 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (Window->state & WNDS_ANSICREATOR) { ANSI_STRING AnsiString; - AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name)+sizeof(CHAR); + AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name) + sizeof(CHAR); pszName = UserHeapAlloc(AnsiString.MaximumLength); + if (!pszName) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } RtlZeroMemory(pszName, AnsiString.MaximumLength); AnsiString.Buffer = (PCHAR)pszName; RtlUnicodeStringToAnsiString(&AnsiString, &Name, FALSE); @@ -2072,11 +2092,16 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, UNICODE_STRING UnicodeString; UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL); pszName = UserHeapAlloc(UnicodeString.MaximumLength); + if (!pszName) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } RtlZeroMemory(pszName, UnicodeString.MaximumLength); UnicodeString.Buffer = (PWSTR)pszName; RtlCopyUnicodeString(&UnicodeString, &Name); } - if (pszName) pCsw->lpszName = UserHeapAddressToUser(pszName); + pCsw->lpszName = UserHeapAddressToUser(pszName); } pCbtCreate->lpcs = pCsw; @@ -2087,7 +2112,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (Result != 0) { DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result); - RETURN( (PWND) NULL); + goto cleanup; } // Write back changes. Cs->cx = pCsw->cx; @@ -2143,7 +2168,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (!Result) { DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n"); - RETURN((PWND)0); + goto cleanup; } /* Send the WM_NCCALCSIZE message */ @@ -2161,7 +2186,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (Result == (LRESULT)-1) { DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n"); - RETURN((PWND)0); + goto cleanup; } /* Send the EVENT_OBJECT_CREATE event*/ @@ -2234,10 +2259,10 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, } DPRINT("co_UserCreateWindowEx(): Created window %X\n", hWnd); - RETURN( Window); + ret = Window; -CLEANUP: - if (!_ret_) +cleanup: + if (!ret) { DPRINT("co_UserCreateWindowEx(): Error Created window!\n"); /* If the window was created, the class will be dereferenced by co_UserDestroyWindow */ @@ -2258,8 +2283,8 @@ CLEANUP: UserDereferenceObject(Window); } if (ParentWindow) UserDerefObjectCo(ParentWindow); - - END_CLEANUP; + + return ret; } NTSTATUS From cd22887a97be9702880cbdb99db5f1e9443b2b6b Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Wed, 23 Mar 2011 15:49:44 +0000 Subject: [PATCH 63/90] [NTOSKRNL] Revert r51108. ProbeForRead doesn't check if memory is readable. Improve comments and replace trick raising exception with call to ExRaiseAccessViolation. [WIN32K] Remove ASSERTs in IntSetSysColors: this function is only called in NtUserSetSysColors in SEH block. It shouldn't crash for NULL pointers. svn path=/trunk/; revision=51126 --- reactos/ntoskrnl/ex/exintrin.c | 12 +----------- reactos/subsystems/win32/win32k/objects/stockobj.c | 3 --- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/reactos/ntoskrnl/ex/exintrin.c b/reactos/ntoskrnl/ex/exintrin.c index 3e9d5c3f6b5..df80cae1064 100644 --- a/reactos/ntoskrnl/ex/exintrin.c +++ b/reactos/ntoskrnl/ex/exintrin.c @@ -104,7 +104,6 @@ ProbeForRead(IN CONST VOID *Address, IN ULONG Alignment) { ULONG_PTR Last, Current = (ULONG_PTR)Address; - CHAR Temp; PAGED_CODE(); /* Only probe if we have a valid length */ @@ -132,16 +131,7 @@ ProbeForRead(IN CONST VOID *Address, ExRaiseAccessViolation(); } - /* Round down to the last page */ - Last = PAGE_ROUND_DOWN(Last) + PAGE_SIZE; - do - { - /* Attempt a read */ - Temp = *(volatile CHAR*)Current; - - /* Go to the next address */ - Current = PAGE_ROUND_DOWN(Current) + PAGE_SIZE; - } while (Current != Last); + /* ProbeForRead doesn't check if memory pages are readable! */ } } diff --git a/reactos/subsystems/win32/win32k/objects/stockobj.c b/reactos/subsystems/win32/win32k/objects/stockobj.c index ca8a5e744e2..1a4a65e3b9f 100644 --- a/reactos/subsystems/win32/win32k/objects/stockobj.c +++ b/reactos/subsystems/win32/win32k/objects/stockobj.c @@ -221,9 +221,6 @@ IntSetSysColors(UINT nColors, CONST INT *Elements, CONST COLORREF *Colors) { UINT i; - ASSERT(Elements); - ASSERT(Colors); - for (i = 0; i < nColors; i++) { if ((UINT)(*Elements) < NUM_SYSCOLORS) From fcd25281d988302454524ff86bd7fc80fb1f27e4 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Wed, 23 Mar 2011 16:22:38 +0000 Subject: [PATCH 64/90] [SHELL32] Sync RunFileDlg to wine. It was crashing for one char input. Add "All files (*.*)" filter to RunDlg and OpenWith dialogs. Improved polish translation. Translators: please localize rest... svn path=/trunk/; revision=51127 --- reactos/dll/win32/shell32/dialogs.c | 271 ++++++++++++++---------- reactos/dll/win32/shell32/lang/bg-BG.rc | 10 +- reactos/dll/win32/shell32/lang/ca-ES.rc | 10 +- reactos/dll/win32/shell32/lang/cs-CZ.rc | 10 +- reactos/dll/win32/shell32/lang/da-DK.rc | 10 +- reactos/dll/win32/shell32/lang/de-DE.rc | 10 +- reactos/dll/win32/shell32/lang/el-GR.rc | 10 +- reactos/dll/win32/shell32/lang/en-GB.rc | 10 +- reactos/dll/win32/shell32/lang/en-US.rc | 10 +- reactos/dll/win32/shell32/lang/es-ES.rc | 10 +- reactos/dll/win32/shell32/lang/fi-FI.rc | 10 +- reactos/dll/win32/shell32/lang/fr-FR.rc | 10 +- reactos/dll/win32/shell32/lang/hu-HU.rc | 10 +- reactos/dll/win32/shell32/lang/it-IT.rc | 10 +- reactos/dll/win32/shell32/lang/ja-JP.rc | 10 +- reactos/dll/win32/shell32/lang/ko-KR.rc | 10 +- reactos/dll/win32/shell32/lang/nl-NL.rc | 10 +- reactos/dll/win32/shell32/lang/no-NO.rc | 10 +- reactos/dll/win32/shell32/lang/pl-PL.rc | 12 +- reactos/dll/win32/shell32/lang/pt-BR.rc | 10 +- reactos/dll/win32/shell32/lang/pt-PT.rc | 10 +- reactos/dll/win32/shell32/lang/ro-RO.rc | 10 +- reactos/dll/win32/shell32/lang/ru-RU.rc | 10 +- reactos/dll/win32/shell32/lang/sk-SK.rc | 10 +- reactos/dll/win32/shell32/lang/sl-SI.rc | 10 +- reactos/dll/win32/shell32/lang/sv-SE.rc | 10 +- reactos/dll/win32/shell32/lang/tr-TR.rc | 10 +- reactos/dll/win32/shell32/lang/uk-UA.rc | 10 +- reactos/dll/win32/shell32/lang/zh-CN.rc | 10 +- reactos/dll/win32/shell32/lang/zh-TW.rc | 10 +- reactos/dll/win32/shell32/she_ocmenu.c | 4 +- reactos/dll/win32/shell32/shell32.spec | 4 +- reactos/dll/win32/shell32/shresdef.h | 12 ++ reactos/dll/win32/shell32/undocshell.h | 15 +- 34 files changed, 422 insertions(+), 176 deletions(-) diff --git a/reactos/dll/win32/shell32/dialogs.c b/reactos/dll/win32/shell32/dialogs.c index 9955e83c7a7..4ea9418bba6 100644 --- a/reactos/dll/win32/shell32/dialogs.c +++ b/reactos/dll/win32/shell32/dialogs.c @@ -25,17 +25,17 @@ typedef struct { HWND hwndOwner ; HICON hIcon ; - LPCSTR lpstrDirectory ; - LPCSTR lpstrTitle ; - LPCSTR lpstrDescription ; + LPCWSTR lpstrDirectory ; + LPCWSTR lpstrTitle ; + LPCWSTR lpstrDescription ; UINT uFlags ; } RUNFILEDLGPARAMS ; -typedef BOOL (*LPFNOFN) (OPENFILENAMEA *) ; +typedef BOOL (WINAPI * LPFNOFN) (OPENFILENAMEW *) ; WINE_DEFAULT_DEBUG_CHANNEL(shell); static INT_PTR CALLBACK RunDlgProc (HWND, UINT, WPARAM, LPARAM) ; -static void FillList (HWND, char *) ; +static void FillList (HWND, char *, BOOL) ; /************************************************************************* @@ -261,20 +261,19 @@ BOOL WINAPI PickIconDlg( } /************************************************************************* - * RunFileDlg [SHELL32.61] + * RunFileDlg [internal] * - * NOTES - * Original name: RunFileDlg (exported by ordinal) + * The Unicode function that is available as ordinal 61 on Windows NT/2000/XP/... */ void WINAPI RunFileDlg( HWND hwndOwner, HICON hIcon, - LPCSTR lpstrDirectory, - LPCSTR lpstrTitle, - LPCSTR lpstrDescription, + LPCWSTR lpstrDirectory, + LPCWSTR lpstrTitle, + LPCWSTR lpstrDescription, UINT uFlags) { - + static const WCHAR resnameW[] = {'S','H','E','L','L','_','R','U','N','_','D','L','G',0}; RUNFILEDLGPARAMS rfdp; HRSRC hRes; LPVOID template; @@ -287,43 +286,105 @@ void WINAPI RunFileDlg( rfdp.lpstrDescription = lpstrDescription; rfdp.uFlags = uFlags; - if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_RUN_DLG", (LPSTR)RT_DIALOG))) - { - MessageBoxA (hwndOwner, "Couldn't find dialog.", "Nix", MB_OK) ; + if (!(hRes = FindResourceW(shell32_hInstance, resnameW, (LPWSTR)RT_DIALOG)) || + !(template = LoadResource(shell32_hInstance, hRes))) + { + ERR("Couldn't load SHELL_RUN_DLG resource\n"); + ShellMessageBoxW(shell32_hInstance, hwndOwner, MAKEINTRESOURCEW(IDS_RUNDLG_ERROR), NULL, MB_OK | MB_ICONERROR); return; - } - if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes))) - { - MessageBoxA (hwndOwner, "Couldn't load dialog.", "Nix", MB_OK) ; - return; - } + } - DialogBoxIndirectParamA((HINSTANCE)GetWindowLongPtrW( hwndOwner, - GWLP_HINSTANCE ), + DialogBoxIndirectParamW(shell32_hInstance, template, hwndOwner, RunDlgProc, (LPARAM)&rfdp); } +/* find the directory that contains the file being run */ +static LPWSTR RunDlg_GetParentDir(LPCWSTR cmdline) +{ + const WCHAR *src; + WCHAR *dest, *result, *result_end=NULL; + static const WCHAR dotexeW[] = {'.','e','x','e',0}; + + result = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(strlenW(cmdline)+5)); + + src = cmdline; + dest = result; + + if (*src == '"') + { + src++; + while (*src && *src != '"') + { + if (*src == '\\') + result_end = dest; + *dest++ = *src++; + } + } + else { + while (*src) + { + if (isspaceW(*src)) + { + *dest = 0; + if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(result)) + break; + strcatW(dest, dotexeW); + if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(result)) + break; + } + else if (*src == '\\') + result_end = dest; + *dest++ = *src++; + } + } + + if (result_end) + { + *result_end = 0; + return result; + } + else + { + HeapFree(GetProcessHeap(), 0, result); + return NULL; + } +} + /* Dialog procedure for RunFileDlg */ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - int ic ; - char *psz, *pdir, szMsg[256]; - static RUNFILEDLGPARAMS *prfdp = NULL ; + RUNFILEDLGPARAMS *prfdp = (RUNFILEDLGPARAMS *)GetWindowLongPtrW(hwnd, DWLP_USER); switch (message) { case WM_INITDIALOG : prfdp = (RUNFILEDLGPARAMS *)lParam ; + SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)prfdp); if (prfdp->lpstrTitle) - SetWindowTextA (hwnd, prfdp->lpstrTitle) ; + SetWindowTextW(hwnd, prfdp->lpstrTitle); + if (prfdp->lpstrDescription) + SetWindowTextW(GetDlgItem(hwnd, IDC_RUNDLG_DESCRIPTION), prfdp->lpstrDescription); + if (prfdp->uFlags & RFF_NOBROWSE) + { + HWND browse = GetDlgItem(hwnd, IDC_RUNDLG_BROWSE); + ShowWindow(browse, SW_HIDE); + EnableWindow(browse, FALSE); + } + if (prfdp->uFlags & RFF_NOLABEL) + ShowWindow(GetDlgItem(hwnd, IDC_RUNDLG_LABEL), SW_HIDE); + if (prfdp->uFlags & RFF_CALCDIRECTORY) + FIXME("RFF_CALCDIRECTORY not supported\n"); - SetClassLongPtrW (hwnd, GCLP_HICON, (LPARAM)prfdp->hIcon) ; - SendMessageW (GetDlgItem (hwnd, 12297), STM_SETICON, - (WPARAM)LoadIconW (NULL, (LPCWSTR)IDI_WINLOGO), 0); - FillList (GetDlgItem (hwnd, 12298), NULL) ; - SetFocus (GetDlgItem (hwnd, 12298)) ; + if (prfdp->hIcon == NULL) + prfdp->hIcon = LoadIconW(NULL, (LPCWSTR)IDI_WINLOGO); + SendMessageW(hwnd, WM_SETICON, ICON_BIG, (LPARAM)prfdp->hIcon); + SendMessageW(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)prfdp->hIcon); + SendMessageW(GetDlgItem(hwnd, IDC_RUNDLG_ICON), STM_SETICON, (WPARAM)prfdp->hIcon, 0); + + FillList (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), NULL, (prfdp->uFlags & RFF_NODEFAULT) == 0) ; + SetFocus (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH)) ; return TRUE ; case WM_COMMAND : @@ -331,46 +392,45 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR { case IDOK : { - HWND htxt = NULL ; - if ((ic = GetWindowTextLengthA (htxt = GetDlgItem (hwnd, 12298)))) + int ic ; + HWND htxt = GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH); + if ((ic = GetWindowTextLengthW (htxt))) { - psz = HeapAlloc( GetProcessHeap(), 0, (ic + 2) ); - GetWindowTextA (htxt, psz, ic + 1) ; - pdir = HeapAlloc( GetProcessHeap(), 0, (ic + 2) ); - if (pdir) - { - char * ptr; - strcpy(pdir, psz); - ptr = strrchr(pdir + 4, '\\'); - if(ptr) - ptr[0] = '\0'; - else - pdir[3] = '\0'; - } - if (ShellExecuteA(NULL, NULL, psz, NULL, pdir, SW_SHOWNORMAL) < (HINSTANCE)33) - { - char *pszSysMsg = NULL ; - FormatMessageA ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError (), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&pszSysMsg, 0, NULL - ) ; - sprintf (szMsg, "Error: %s", pszSysMsg) ; - LocalFree ((HLOCAL)pszSysMsg) ; - MessageBoxA (hwnd, szMsg, NULL, MB_OK | MB_ICONEXCLAMATION) ; + WCHAR *psz, *parent=NULL ; + SHELLEXECUTEINFOW sei ; + ZeroMemory (&sei, sizeof(sei)) ; + sei.cbSize = sizeof(sei) ; + psz = HeapAlloc( GetProcessHeap(), 0, (ic + 1)*sizeof(WCHAR) ); + GetWindowTextW (htxt, psz, ic + 1) ; + + /* according to http://www.codeproject.com/KB/shell/runfiledlg.aspx we should send a + * WM_NOTIFY before execution */ + + sei.hwnd = hwnd; + sei.nShow = SW_SHOWNORMAL; + sei.lpFile = psz; + + if (prfdp->lpstrDirectory) + sei.lpDirectory = prfdp->lpstrDirectory; + else + sei.lpDirectory = parent = RunDlg_GetParentDir(sei.lpFile); + + if (!ShellExecuteExW( &sei )) + { HeapFree(GetProcessHeap(), 0, psz); - HeapFree(GetProcessHeap(), 0, pdir); + HeapFree(GetProcessHeap(), 0, parent); SendMessageA (htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; return TRUE ; - } - FillList (htxt, psz) ; + } + + /* FillList is still ANSI */ + GetWindowTextA (htxt, (LPSTR)psz, ic + 1) ; + FillList (htxt, (LPSTR)psz, FALSE) ; + HeapFree(GetProcessHeap(), 0, psz); - HeapFree(GetProcessHeap(), 0, pdir); - EndDialog (hwnd, 0) ; + HeapFree(GetProcessHeap(), 0, parent); + EndDialog (hwnd, 0); } } @@ -378,55 +438,43 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR EndDialog (hwnd, 0) ; return TRUE ; - case 12288 : + case IDC_RUNDLG_BROWSE : { HMODULE hComdlg = NULL ; LPFNOFN ofnProc = NULL ; - static char szFName[1024] = "", szFileTitle[256] = "", szInitDir[768] = "" ; - static OPENFILENAMEA ofn = - { - sizeof (OPENFILENAMEA), - NULL, - NULL, - "Executable Files\0*.exe\0All Files\0*.*\0\0\0\0", - NULL, - 0, - 0, - szFName, - 1023, - szFileTitle, - 255, - (LPCSTR)szInitDir, - "Browse", - OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, - 0, - 0, - NULL, - 0, - (LPOFNHOOKPROC)NULL, - NULL - } ; + static const WCHAR comdlg32W[] = {'c','o','m','d','l','g','3','2',0}; + WCHAR szFName[1024] = {0}; + WCHAR filter[MAX_PATH], szCaption[MAX_PATH]; + OPENFILENAMEW ofn; - ofn.hwndOwner = hwnd ; + LoadStringW(shell32_hInstance, IDS_RUNDLG_BROWSE_FILTER, filter, MAX_PATH); + LoadStringW(shell32_hInstance, IDS_RUNDLG_BROWSE_CAPTION, szCaption, MAX_PATH); - if (NULL == (hComdlg = LoadLibraryExA ("comdlg32", NULL, 0))) - { - MessageBoxA (hwnd, "Unable to display dialog box (LoadLibraryEx) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ; + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(OPENFILENAMEW); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = filter; + ofn.lpstrFile = szFName; + ofn.nMaxFile = 1023; + ofn.lpstrTitle = szCaption; + ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = prfdp->lpstrDirectory; + + if (NULL == (hComdlg = LoadLibraryExW (comdlg32W, NULL, 0)) || + NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameW"))) + { + ERR("Couldn't get GetOpenFileName function entry (lib=%p, proc=%p)\n", hComdlg, ofnProc); + ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_RUNDLG_BROWSE_ERROR), NULL, MB_OK | MB_ICONERROR); return TRUE ; - } + } - if ((LPFNOFN)NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameA"))) - { - MessageBoxA (hwnd, "Unable to display dialog box (GetProcAddress) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ; - return TRUE ; - } - - ofnProc (&ofn) ; - - SetFocus (GetDlgItem (hwnd, IDOK)) ; - SetWindowTextA (GetDlgItem (hwnd, 12298), szFName) ; - SendMessageA (GetDlgItem (hwnd, 12298), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; - SetFocus (GetDlgItem (hwnd, IDOK)) ; + if (ofnProc(&ofn)) + { + SetFocus (GetDlgItem (hwnd, IDOK)) ; + SetWindowTextW (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), szFName) ; + SendMessageW (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; + SetFocus (GetDlgItem (hwnd, IDOK)) ; + } FreeLibrary (hComdlg) ; @@ -439,7 +487,8 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR } /* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */ -static void FillList (HWND hCb, char *pszLatest) +/* fShowDefault ignored if pszLatest != NULL */ +static void FillList (HWND hCb, char *pszLatest, BOOL fShowDefault) { HKEY hkey ; /* char szDbgMsg[256] = "" ; */ @@ -511,7 +560,7 @@ static void FillList (HWND hCb, char *pszLatest) MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; */ SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ; - if (!Nix) + if (!Nix && fShowDefault) { SetWindowTextA (hCb, pszCmd) ; SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; @@ -609,6 +658,7 @@ int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, D return 0; } + /************************************************************************* * LogoffWindowsDialog [SHELL32.54] */ @@ -622,6 +672,7 @@ int WINAPI LogoffWindowsDialog(HWND hWndOwner) return 0; } + /************************************************************************* * RestartDialog [SHELL32.59] */ diff --git a/reactos/dll/win32/shell32/lang/bg-BG.rc b/reactos/dll/win32/shell32/lang/bg-BG.rc index 6e9b67ad41f..36a5cf5e23b 100644 --- a/reactos/dll/win32/shell32/lang/bg-BG.rc +++ b/reactos/dll/win32/shell32/lang/bg-BG.rc @@ -669,6 +669,12 @@ BEGIN IDS_LOGOFF_TITLE "Čçëčçŕíĺ" IDS_LOGOFF_PROMPT "Čńęŕňĺ ëč äŕ čçëĺçĺňĺ?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + // shell folder path default values IDS_PROGRAMS "Ďóńęîâ čçáîđíčę\\Ďđčëîćĺíč˙" IDS_PERSONAL "Ęíčćŕ" @@ -718,8 +724,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Ńâîáîäíî ě˙ńňî" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Čçáĺđĺňĺ çíŕ÷ĺ" - IDS_PICK_ICON_FILTER "Ôŕéëîâĺ ńúń çíŕ÷ĺňŕ(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Čçďúëíčěč ôŕéëîâĺ\0*.exe\0" + IDS_PICK_ICON_FILTER "Ôŕéëîâĺ ńúń çíŕ÷ĺňŕ (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Čçďúëíčěč ôŕéëîâĺ (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Ďŕďęŕ" IDS_VIRTUAL_DRIVER "Âîäŕ÷ íŕ ďđčâčäíî óńňđîéńňâî" IDS_BAT_FILE "Ďŕęĺňĺí ôŕéë íŕ ĐĺŕęňÎŃ" diff --git a/reactos/dll/win32/shell32/lang/ca-ES.rc b/reactos/dll/win32/shell32/lang/ca-ES.rc index 214028e7d8e..80f7cb41b05 100644 --- a/reactos/dll/win32/shell32/lang/ca-ES.rc +++ b/reactos/dll/win32/shell32/lang/ca-ES.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/cs-CZ.rc b/reactos/dll/win32/shell32/lang/cs-CZ.rc index dff2e85bff0..728fce9fd08 100644 --- a/reactos/dll/win32/shell32/lang/cs-CZ.rc +++ b/reactos/dll/win32/shell32/lang/cs-CZ.rc @@ -655,6 +655,12 @@ BEGIN IDS_LOGOFF_TITLE "Odhlásit se" IDS_LOGOFF_PROMPT "Opravdu se chcete odhlásit?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Nabídka Start\\Programy" IDS_PERSONAL "Dokumenty" @@ -704,8 +710,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Dostupné místo" IDS_EMPTY_BITBUCKET "Vysypat koš" IDS_PICK_ICON_TITLE "Zvolit ikonu" - IDS_PICK_ICON_FILTER "Soubory ikon (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Spustitelné soubory\0*.exe\0" + IDS_PICK_ICON_FILTER "Soubory ikon (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Spustitelné soubory (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Složka" IDS_VIRTUAL_DRIVER "Virtuální ovladač zařízení" IDS_BAT_FILE "ReactOS dávkový soubor" diff --git a/reactos/dll/win32/shell32/lang/da-DK.rc b/reactos/dll/win32/shell32/lang/da-DK.rc index 9ad423c95e4..00472085917 100644 --- a/reactos/dll/win32/shell32/lang/da-DK.rc +++ b/reactos/dll/win32/shell32/lang/da-DK.rc @@ -657,6 +657,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programmer" IDS_PERSONAL "Mine Dokumenter" @@ -706,8 +712,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/de-DE.rc b/reactos/dll/win32/shell32/lang/de-DE.rc index 5610af6fa30..62921561703 100644 --- a/reactos/dll/win32/shell32/lang/de-DE.rc +++ b/reactos/dll/win32/shell32/lang/de-DE.rc @@ -672,6 +672,12 @@ BEGIN IDS_LOGOFF_TITLE "Ausloggen" IDS_LOGOFF_PROMPT "Möchten Sie sich ausloggen?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Startmenü\\Programme" IDS_PERSONAL "Eigene Dateien" @@ -721,8 +727,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "freier Speicher" IDS_EMPTY_BITBUCKET "Papierkorb leeren" IDS_PICK_ICON_TITLE "Symbol auswählen" - IDS_PICK_ICON_FILTER "Symboldateien(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Programme\0*.exe\0" + IDS_PICK_ICON_FILTER "Symboldateien (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Programme (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Dateiordner" IDS_VIRTUAL_DRIVER "Virtueller Gerätetreiber" IDS_BAT_FILE "ReactOS-Stapelverarbeitungsdatei" diff --git a/reactos/dll/win32/shell32/lang/el-GR.rc b/reactos/dll/win32/shell32/lang/el-GR.rc index a269d68ed2f..80506a2cedf 100644 --- a/reactos/dll/win32/shell32/lang/el-GR.rc +++ b/reactos/dll/win32/shell32/lang/el-GR.rc @@ -669,6 +669,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "Ôá ÝăăńáöÜ ěďő" @@ -718,8 +724,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/en-GB.rc b/reactos/dll/win32/shell32/lang/en-GB.rc index 5d8f02c9a47..0b9ff3f713d 100644 --- a/reactos/dll/win32/shell32/lang/en-GB.rc +++ b/reactos/dll/win32/shell32/lang/en-GB.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/en-US.rc b/reactos/dll/win32/shell32/lang/en-US.rc index 04df98d1e60..6eaac708f7a 100644 --- a/reactos/dll/win32/shell32/lang/en-US.rc +++ b/reactos/dll/win32/shell32/lang/en-US.rc @@ -679,6 +679,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -728,8 +734,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/es-ES.rc b/reactos/dll/win32/shell32/lang/es-ES.rc index c619493d3f2..1b48d7953db 100644 --- a/reactos/dll/win32/shell32/lang/es-ES.rc +++ b/reactos/dll/win32/shell32/lang/es-ES.rc @@ -681,6 +681,12 @@ BEGIN IDS_LOGOFF_TITLE "Cerrar sesión" IDS_LOGOFF_PROMPT "żDesea cerrar la sesión?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menú Inicio\\Programas" IDS_PERSONAL "Mis documentos" @@ -730,8 +736,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Espacio disponible" IDS_EMPTY_BITBUCKET "Vaciar Papelera de reciclaje" IDS_PICK_ICON_TITLE "Seleccione un icono" - IDS_PICK_ICON_FILTER "Archivos de iconos(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Programas\0*.exe\0" + IDS_PICK_ICON_FILTER "Archivos de iconos (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Programas (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Directorio" IDS_VIRTUAL_DRIVER "Controlador de dispositivo virtual" IDS_BAT_FILE "Archivo por lotes ReactOS" diff --git a/reactos/dll/win32/shell32/lang/fi-FI.rc b/reactos/dll/win32/shell32/lang/fi-FI.rc index 6469ce1b7b5..125a07d9c50 100644 --- a/reactos/dll/win32/shell32/lang/fi-FI.rc +++ b/reactos/dll/win32/shell32/lang/fi-FI.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Käynnistä\\Ohjelmat" IDS_PERSONAL "Omat tiedostot" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/fr-FR.rc b/reactos/dll/win32/shell32/lang/fr-FR.rc index 0ba3b4473f2..4083d654d9a 100644 --- a/reactos/dll/win32/shell32/lang/fr-FR.rc +++ b/reactos/dll/win32/shell32/lang/fr-FR.rc @@ -672,6 +672,12 @@ BEGIN IDS_LOGOFF_TITLE "Se déconnecter" IDS_LOGOFF_PROMPT "Voulez-vous vous déconnecter ?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Démarrer\\Programmes" IDS_PERSONAL "Mes documents" @@ -721,8 +727,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Espace disponible" IDS_EMPTY_BITBUCKET "Vider la Corbeille" IDS_PICK_ICON_TITLE "Choisir une icône" - IDS_PICK_ICON_FILTER "Fichiers d'icônes (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Fichiers exécutables\0*.exe\0" + IDS_PICK_ICON_FILTER "Fichiers d'icônes (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Fichiers exécutables (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Dossier" IDS_VIRTUAL_DRIVER "Pilote de périphérique virtuel" IDS_BAT_FILE "Fichier Batch ReactOS" diff --git a/reactos/dll/win32/shell32/lang/hu-HU.rc b/reactos/dll/win32/shell32/lang/hu-HU.rc index e45819a2d47..7eb015d8ced 100644 --- a/reactos/dll/win32/shell32/lang/hu-HU.rc +++ b/reactos/dll/win32/shell32/lang/hu-HU.rc @@ -671,6 +671,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "Dokumentumok" @@ -720,8 +726,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/it-IT.rc b/reactos/dll/win32/shell32/lang/it-IT.rc index 824eb22a88e..09251b6fc34 100644 --- a/reactos/dll/win32/shell32/lang/it-IT.rc +++ b/reactos/dll/win32/shell32/lang/it-IT.rc @@ -679,6 +679,12 @@ BEGIN IDS_LOGOFF_TITLE "Disconnetti" IDS_LOGOFF_PROMPT "Volete disconnettervi?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Avvio\\Programmi" IDS_PERSONAL "Documenti Personali" @@ -728,8 +734,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Spazio disponibile" IDS_EMPTY_BITBUCKET "Svuota cestino" IDS_PICK_ICON_TITLE "Scegliere un icona" - IDS_PICK_ICON_FILTER "Icone(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "File eseguibili\0*.exe\0" + IDS_PICK_ICON_FILTER "Icone (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "File eseguibili (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Cartella" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/ja-JP.rc b/reactos/dll/win32/shell32/lang/ja-JP.rc index c09ba106660..a671c6137a2 100644 --- a/reactos/dll/win32/shell32/lang/ja-JP.rc +++ b/reactos/dll/win32/shell32/lang/ja-JP.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "X^[g j…[\\vŤO‰€" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "——p‚Ĺ‚«‚é—Ěć" IDS_EMPTY_BITBUCKET "‚˛‚Ý” ‚đ‹ó‚É‚·‚é" IDS_PICK_ICON_TITLE "ACR“‚Ě‘I‘đ" - IDS_PICK_ICON_FILTER "ACR“t@C‹(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "ŽŔŤs‰Â”\\ t@C‹\0*.exe\0" + IDS_PICK_ICON_FILTER "ACR“t@C‹ (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "ŽŔŤs‰Â”\\ t@C‹ (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "tH‹_" IDS_VIRTUAL_DRIVER "‰Ľ‘z foCX h‰Co" IDS_BAT_FILE "ReactOS ob` t@C‹" diff --git a/reactos/dll/win32/shell32/lang/ko-KR.rc b/reactos/dll/win32/shell32/lang/ko-KR.rc index 98981f74213..b5d0dfa5c91 100644 --- a/reactos/dll/win32/shell32/lang/ko-KR.rc +++ b/reactos/dll/win32/shell32/lang/ko-KR.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/nl-NL.rc b/reactos/dll/win32/shell32/lang/nl-NL.rc index 1689e2a3bae..fa176ce352d 100644 --- a/reactos/dll/win32/shell32/lang/nl-NL.rc +++ b/reactos/dll/win32/shell32/lang/nl-NL.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/no-NO.rc b/reactos/dll/win32/shell32/lang/no-NO.rc index f02aa64fecd..e576cb47d54 100644 --- a/reactos/dll/win32/shell32/lang/no-NO.rc +++ b/reactos/dll/win32/shell32/lang/no-NO.rc @@ -671,6 +671,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start-meny\\Programmer" IDS_PERSONAL "Mine dokumenter" @@ -720,8 +726,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Ledig plass" IDS_EMPTY_BITBUCKET "Třm papirkurven" IDS_PICK_ICON_TITLE "Velg Ikon" - IDS_PICK_ICON_FILTER "Ikon Fil(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Kjřrbare filer\0*.exe\0" + IDS_PICK_ICON_FILTER "Ikon Fil (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Kjřrbare filer (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Mappe" IDS_VIRTUAL_DRIVER "Virtuell enhetdriver" IDS_BAT_FILE "ReactOS Batch fil" diff --git a/reactos/dll/win32/shell32/lang/pl-PL.rc b/reactos/dll/win32/shell32/lang/pl-PL.rc index c9a4d40a48b..cb33116bd45 100644 --- a/reactos/dll/win32/shell32/lang/pl-PL.rc +++ b/reactos/dll/win32/shell32/lang/pl-PL.rc @@ -675,6 +675,12 @@ BEGIN IDS_LOGOFF_TITLE "Wyloguj" IDS_LOGOFF_PROMPT "Czy chcesz się wylogować z systemu?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Nie mogę wyświetlić okna Uruchom (błąd wewnętrzny)" + IDS_RUNDLG_BROWSE_ERROR "Nie mogę wyświetlić okna Przeglądaj (błąd wewnętrzny)" + IDS_RUNDLG_BROWSE_CAPTION "Przeglądaj" + IDS_RUNDLG_BROWSE_FILTER "Programy (*.exe)\0*.exe\0Wszystkie pliki (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Start\\Programy" IDS_PERSONAL "Moje dokumenty" @@ -724,8 +730,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Pozostało wolnego miejsca" IDS_EMPTY_BITBUCKET "Opróżnij Kosz" IDS_PICK_ICON_TITLE "Wybierz ikonę" - IDS_PICK_ICON_FILTER "Pliki ikon(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Programy\0*.exe\0" + IDS_PICK_ICON_FILTER "Pliki ikon (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0Wszystkie pliki (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Programy (*.exe)\0*.exe\0Wszystkie pliki (*.*)\0*.*\0" IDS_DIRECTORY "Katalog" IDS_VIRTUAL_DRIVER "Sterownik urządzenia wirtualnego" IDS_BAT_FILE "Plik wsadowy ReactOS" @@ -759,5 +765,5 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Domyślny rozmiar jednostki alokacji" IDS_COPY_OF "Kopia" - IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." + IDS_SHLEXEC_NOASSOC "Żaden program nie jest skonfigurowane by otwierać pliki tego typu." END diff --git a/reactos/dll/win32/shell32/lang/pt-BR.rc b/reactos/dll/win32/shell32/lang/pt-BR.rc index 7679014ff37..ef97edbea18 100644 --- a/reactos/dll/win32/shell32/lang/pt-BR.rc +++ b/reactos/dll/win32/shell32/lang/pt-BR.rc @@ -670,6 +670,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Iniciar\\Programas" IDS_PERSONAL "Meus Documentos" @@ -719,8 +725,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/pt-PT.rc b/reactos/dll/win32/shell32/lang/pt-PT.rc index 2d99ca47e97..6daead85f4a 100644 --- a/reactos/dll/win32/shell32/lang/pt-PT.rc +++ b/reactos/dll/win32/shell32/lang/pt-PT.rc @@ -671,6 +671,12 @@ BEGIN IDS_LOGOFF_TITLE "Terminar a sessăo" IDS_LOGOFF_PROMPT "Pretende terminar a sessăo?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Iniciar\\Programas" IDS_PERSONAL "OS Meus Documentos" @@ -720,8 +726,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Espaço Disponível" IDS_EMPTY_BITBUCKET "Esvaziar Reciclagem" IDS_PICK_ICON_TITLE "Escolha Ícone" - IDS_PICK_ICON_FILTER "Ficheiros de Ícones(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Ficheiros Executáveis\0*.exe\0" + IDS_PICK_ICON_FILTER "Ficheiros de Ícones (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Ficheiros Executáveis (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Pasta" IDS_VIRTUAL_DRIVER "Driver de Dispositivo Virtual" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/ro-RO.rc b/reactos/dll/win32/shell32/lang/ro-RO.rc index fb24c2ba437..47d05ffc62a 100644 --- a/reactos/dll/win32/shell32/lang/ro-RO.rc +++ b/reactos/dll/win32/shell32/lang/ro-RO.rc @@ -671,6 +671,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Meniu Start\\Programe" IDS_PERSONAL "Documentele mele" @@ -720,8 +726,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "SpaČ›iu disponibil" IDS_EMPTY_BITBUCKET "Golire CoČ™ de gunoi" IDS_PICK_ICON_TITLE "Alegere pictogramÄ" - IDS_PICK_ICON_FILTER "FiČ™iere pictogramÄ (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "FiČ™iere executabile\0*.exe\0" + IDS_PICK_ICON_FILTER "FiČ™iere pictogramÄ (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "FiČ™iere executabile (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Dosar" IDS_VIRTUAL_DRIVER "Driver dispozitiv virtual" IDS_BAT_FILE "FiČ™ier serie de comenzi ReactOS" diff --git a/reactos/dll/win32/shell32/lang/ru-RU.rc b/reactos/dll/win32/shell32/lang/ru-RU.rc index daf4f2ce16b..b3ecbdb4909 100644 --- a/reactos/dll/win32/shell32/lang/ru-RU.rc +++ b/reactos/dll/win32/shell32/lang/ru-RU.rc @@ -667,6 +667,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Ăëŕâíîĺ ěĺíţ\\Ďđîăđŕěěű" IDS_PERSONAL "Ěîč äîęóěĺíňű" @@ -716,8 +722,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Äîńňóďíîĺ ďđîńňđŕíńňâî" IDS_EMPTY_BITBUCKET "Î÷čńňčňü ęîđçčíó" IDS_PICK_ICON_TITLE "Âűáđŕňü çíŕ÷îę" - IDS_PICK_ICON_FILTER "Ôŕéëű çíŕ÷ęîâ(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Čńďîëí˙ĺěűĺ ôŕéëű\0*.exe\0" + IDS_PICK_ICON_FILTER "Ôŕéëű çíŕ÷ęîâ (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Čńďîëí˙ĺěűĺ ôŕéëű (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Ďŕďęŕ" IDS_VIRTUAL_DRIVER "Äđŕéâĺđ âčđňóŕëüíîăî óńňđîéńňâŕ" IDS_BAT_FILE "Ďŕęĺňíűé ôŕéë ReactOS" diff --git a/reactos/dll/win32/shell32/lang/sk-SK.rc b/reactos/dll/win32/shell32/lang/sk-SK.rc index 848d343ecdd..7620ce08536 100644 --- a/reactos/dll/win32/shell32/lang/sk-SK.rc +++ b/reactos/dll/win32/shell32/lang/sk-SK.rc @@ -674,6 +674,12 @@ BEGIN IDS_LOGOFF_TITLE "Odhlásiť" IDS_LOGOFF_PROMPT "Naozaj sa chcete odhlásiť?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Ponuka Štart\\Programy" IDS_PERSONAL "Moje dokumenty" @@ -723,8 +729,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Dostupné miesto" IDS_EMPTY_BITBUCKET "Vyprázdniť Kôš" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Súbory ikon(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Spustiteľné súbory\0*.exe\0" + IDS_PICK_ICON_FILTER "Súbory ikon (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Spustiteľné súbory (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Priečinok" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "Dávkový súbor systému ReactOS" diff --git a/reactos/dll/win32/shell32/lang/sl-SI.rc b/reactos/dll/win32/shell32/lang/sl-SI.rc index 9789ec3841c..594cdf88181 100644 --- a/reactos/dll/win32/shell32/lang/sl-SI.rc +++ b/reactos/dll/win32/shell32/lang/sl-SI.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/sv-SE.rc b/reactos/dll/win32/shell32/lang/sv-SE.rc index 4ddd5c36520..0238edfae66 100644 --- a/reactos/dll/win32/shell32/lang/sv-SE.rc +++ b/reactos/dll/win32/shell32/lang/sv-SE.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/tr-TR.rc b/reactos/dll/win32/shell32/lang/tr-TR.rc index 633936f625a..d5ca8c1fb25 100644 --- a/reactos/dll/win32/shell32/lang/tr-TR.rc +++ b/reactos/dll/win32/shell32/lang/tr-TR.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programlar" IDS_PERSONAL "Belgelerim" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/uk-UA.rc b/reactos/dll/win32/shell32/lang/uk-UA.rc index b65aea75945..bd2cfda8c93 100644 --- a/reactos/dll/win32/shell32/lang/uk-UA.rc +++ b/reactos/dll/win32/shell32/lang/uk-UA.rc @@ -681,6 +681,12 @@ BEGIN IDS_LOGOFF_TITLE "Âčőłä ç ńčńňĺěč" IDS_LOGOFF_PROMPT "Âč őî÷ĺňĺ âčéňč ç ńčńňĺěč?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "Ěîż äîęóěĺíňč" @@ -730,8 +736,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Äîńňóďíčé ďđîńňłđ" IDS_EMPTY_BITBUCKET "Î÷čńňčňč Ęîřčę" IDS_PICK_ICON_TITLE "Âčáđŕňč çíŕ÷îę" - IDS_PICK_ICON_FILTER "Ôŕéëč çíŕ÷ęłâ(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Âčęîíóâŕíł ôŕéëč\0*.exe\0" + IDS_PICK_ICON_FILTER "Ôŕéëč çíŕ÷ęłâ (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Âčęîíóâŕíł ôŕéëč (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Ďŕďęŕ" IDS_VIRTUAL_DRIVER "Äđŕéâĺđ âłđňóŕëüíîăî ďđčńňđîţ" IDS_BAT_FILE "Ďŕęĺňíčé ôŕéë ReactOS" diff --git a/reactos/dll/win32/shell32/lang/zh-CN.rc b/reactos/dll/win32/shell32/lang/zh-CN.rc index aa54e3eecb6..693a2890407 100644 --- a/reactos/dll/win32/shell32/lang/zh-CN.rc +++ b/reactos/dll/win32/shell32/lang/zh-CN.rc @@ -657,6 +657,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "ÎҵÄÎĵµ" @@ -705,8 +711,8 @@ BEGIN IDS_RECYCLEBIN_LOCATION "Recycle Bin Location" IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/lang/zh-TW.rc b/reactos/dll/win32/shell32/lang/zh-TW.rc index fcf7abf9f7b..ea14a6d300c 100644 --- a/reactos/dll/win32/shell32/lang/zh-TW.rc +++ b/reactos/dll/win32/shell32/lang/zh-TW.rc @@ -669,6 +669,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -718,8 +724,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/reactos/dll/win32/shell32/she_ocmenu.c b/reactos/dll/win32/shell32/she_ocmenu.c index c2e9c05ede5..9aea9e1b48e 100644 --- a/reactos/dll/win32/shell32/she_ocmenu.c +++ b/reactos/dll/win32/shell32/she_ocmenu.c @@ -537,8 +537,8 @@ SetProgrammAsDefaultHandler(LPCWSTR szFileName, WCHAR * szAppName) void BrowseForApplication(HWND hwndDlg) { - WCHAR szBuffer[30] = {0}; - WCHAR szFilter[30] = {0}; + WCHAR szBuffer[64] = {0}; + WCHAR szFilter[256] = {0}; WCHAR szPath[MAX_PATH]; OPENFILENAMEW ofn; OPEN_WITH_CONTEXT Context; diff --git a/reactos/dll/win32/shell32/shell32.spec b/reactos/dll/win32/shell32/shell32.spec index bb7e0d23c09..8c9b3883824 100644 --- a/reactos/dll/win32/shell32/shell32.spec +++ b/reactos/dll/win32/shell32/shell32.spec @@ -58,9 +58,9 @@ 58 stdcall -noname ParseField(str long ptr long) ParseFieldAW # Fixme 59 stdcall RestartDialog(long wstr long) 60 stdcall -noname ExitWindowsDialog(long) # Fixme -61 stdcall -noname RunFileDlg(long long long str str long) RunFileDlg # Fixme +61 stdcall -noname RunFileDlg(long long long wstr wstr long) RunFileDlg # Fixme? 62 stdcall PickIconDlg(long long long long) -63 stdcall GetFileNameFromBrowse(long long long long str str str) +63 stdcall GetFileNameFromBrowse(long long long long wstr wstr wstr) 64 stdcall DriveType(long) 65 stdcall -noname InvalidateDriveType(long) 66 stdcall IsNetDrive(long) diff --git a/reactos/dll/win32/shell32/shresdef.h b/reactos/dll/win32/shell32/shresdef.h index 43e409cbf44..23ff1ecfd2c 100644 --- a/reactos/dll/win32/shell32/shresdef.h +++ b/reactos/dll/win32/shell32/shresdef.h @@ -142,6 +142,11 @@ #define IDS_FILE_TYPES 174 #define IDS_FILE_DETAILS 175 +#define IDS_RUNDLG_ERROR 180 +#define IDS_RUNDLG_BROWSE_ERROR 181 +#define IDS_RUNDLG_BROWSE_CAPTION 182 +#define IDS_RUNDLG_BROWSE_FILTER 183 + #define IDS_OPEN_VERB 300 #define IDS_RUNAS_VERB 301 #define IDS_EDIT_VERB 302 @@ -195,6 +200,13 @@ #define OPEN_WITH_PROGRAMM_DLG 0x4001 #define IDD_SH_FILE_COPY 0x4002 +/* run dialog */ +#define IDC_RUNDLG_DESCRIPTION 12289 +#define IDC_RUNDLG_BROWSE 12288 +#define IDC_RUNDLG_ICON 12297 +#define IDC_RUNDLG_EDITPATH 12298 +#define IDC_RUNDLG_LABEL 12305 + /* ID's of the ShellAbout controls */ // Part 1 - ID's identical to Windows Server 2003 SP1's shell32.dll #define IDD_SHELL_ABOUT 0x3810 diff --git a/reactos/dll/win32/shell32/undocshell.h b/reactos/dll/win32/shell32/undocshell.h index 8911967b694..f9ec7cdb5ce 100644 --- a/reactos/dll/win32/shell32/undocshell.h +++ b/reactos/dll/win32/shell32/undocshell.h @@ -70,6 +70,15 @@ HRESULT WINAPI SHILCreateFromPathW ( BOOL WINAPI StrRetToStrNA(LPSTR,DWORD,LPSTRRET,const ITEMIDLIST*); BOOL WINAPI StrRetToStrNW(LPWSTR,DWORD,LPSTRRET,const ITEMIDLIST*); + +/**************************************************************************** +* SHChangeNotifyRegister API +*/ +#define SHCNRF_InterruptLevel 0x0001 +#define SHCNRF_ShellLevel 0x0002 +#define SHCNRF_RecursiveInterrupt 0x1000 /* Must be combined with SHCNRF_InterruptLevel */ +#define SHCNRF_NewDelivery 0x8000 /* Messages use shared memory */ + /**************************************************************************** * Shell Common Dialogs */ @@ -100,9 +109,9 @@ typedef struct void WINAPI RunFileDlg( HWND hwndOwner, HICON hIcon, - LPCSTR lpstrDirectory, - LPCSTR lpstrTitle, - LPCSTR lpstrDescription, + LPCWSTR lpstrDirectory, + LPCWSTR lpstrTitle, + LPCWSTR lpstrDescription, UINT uFlags); void WINAPI ExitWindowsDialog(HWND hwndOwner); From cd1a61c18ff5cbab38e6b3ea82f976b3ed2af83b Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Wed, 23 Mar 2011 16:51:26 +0000 Subject: [PATCH 65/90] [USER32] Gray close button if SC_CLOSE is disabled is sysmenu or class has CS_NOCLOSE flag See issue #5272 for more details. svn path=/trunk/; revision=51128 --- reactos/dll/win32/user32/windows/nonclient.c | 32 ++++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/reactos/dll/win32/user32/windows/nonclient.c b/reactos/dll/win32/user32/windows/nonclient.c index 1d825b978df..19f18256f15 100644 --- a/reactos/dll/win32/user32/windows/nonclient.c +++ b/reactos/dll/win32/user32/windows/nonclient.c @@ -161,7 +161,7 @@ UserDrawSysMenuButton(HWND hWnd, HDC hDC, LPRECT Rect, BOOL Down) * - Center the buttons verticaly in the rect */ VOID -UserDrawCaptionButton(LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDown, ULONG Type) +UserDrawCaptionButton(HWND hWnd, LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDown, ULONG Type) { RECT TempRect; @@ -214,6 +214,9 @@ UserDrawCaptionButton(LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDo } case DFCS_CAPTIONCLOSE: { + HMENU hSysMenu = GetSystemMenu(hWnd, FALSE); + UINT MenuState = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */ + /* FIXME: A tool window has a smaller Close button */ if (ExStyle & WS_EX_TOOLWINDOW) @@ -231,7 +234,7 @@ UserDrawCaptionButton(LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDo DrawFrameControl(hDC, &TempRect, DFC_CAPTION, (DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) | - ((Style & WS_SYSMENU) ? 0 : DFCS_INACTIVE))); + ((!(MenuState & (MF_GRAYED|MF_DISABLED)) && !(GetClassLong(hWnd, GCL_STYLE) & CS_NOCLOSE)) ? 0 : DFCS_INACTIVE))); break; } } @@ -252,7 +255,7 @@ UserDrawCaptionButtonWnd(HWND hWnd, HDC hDC, BOOL bDown, ULONG Type) ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE); UserGetWindowBorders(Style, ExStyle, &WindowBorder, FALSE); InflateRect(&WindowRect, -WindowBorder.cx, -WindowBorder.cy); - UserDrawCaptionButton(&WindowRect, Style, ExStyle, hDC, bDown, Type); + UserDrawCaptionButton(hWnd, &WindowRect, Style, ExStyle, hDC, bDown, Type); } // Note from Wine: @@ -419,11 +422,11 @@ DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active) /* Draw buttons */ if (Style & WS_SYSMENU) { - UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE); + UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE); if ((Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(ExStyle & WS_EX_TOOLWINDOW)) { - UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN); - UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX); + UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN); + UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX); } } if(!(Style & WS_MINIMIZE)) @@ -665,8 +668,8 @@ DefWndNCHitTest(HWND hWnd, POINT Point) RECT WindowRect, ClientRect, OrigWndRect; POINT ClientPoint; SIZE WindowBorders; - ULONG Style = GetWindowLongPtrW(hWnd, GWL_STYLE); - ULONG ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE); + DWORD Style = GetWindowLongPtrW(hWnd, GWL_STYLE); + DWORD ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE); GetWindowRect(hWnd, &WindowRect); if (!PtInRect(&WindowRect, Point)) @@ -787,8 +790,6 @@ DefWndNCHitTest(HWND hWnd, POINT Point) if(!(Style & WS_MINIMIZE)) { - HMENU menu; - ClientPoint = Point; ScreenToClient(hWnd, &ClientPoint); GetClientRect(hWnd, &ClientRect); @@ -798,7 +799,7 @@ DefWndNCHitTest(HWND hWnd, POINT Point) return HTCLIENT; } - if ((menu = GetMenu(hWnd)) && !(Style & WS_CHILD)) + if (GetMenu(hWnd) && !(Style & WS_CHILD)) { if (Point.x > 0 && Point.x < WindowRect.right && ClientPoint.y < 0) return HTMENU; @@ -878,13 +879,18 @@ DefWndDoButton(HWND hWnd, WPARAM wParam) HDC WindowDC; BOOL Pressed = TRUE, OldState; WPARAM SCMsg; - ULONG ButtonType, Style; + HMENU hSysMenu; + ULONG ButtonType; + DWORD Style; + UINT MenuState; Style = GetWindowLongPtrW(hWnd, GWL_STYLE); switch (wParam) { case HTCLOSE: - if (!(Style & WS_SYSMENU)) + hSysMenu = GetSystemMenu(hWnd, FALSE); + MenuState = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */ + if (!(Style & WS_SYSMENU) || (MenuState & (MF_GRAYED|MF_DISABLED)) || (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_NOCLOSE)) return; ButtonType = DFCS_CAPTIONCLOSE; SCMsg = SC_CLOSE; From 4732a3af3de1a03808cac55650f3ab4edb610807 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Wed, 23 Mar 2011 17:11:40 +0000 Subject: [PATCH 66/90] [WIN32K] Remove a useless if in cliprgn.c Patch by Thomas Faber See issue #6015 for more details. svn path=/trunk/; revision=51129 --- reactos/subsystems/win32/win32k/objects/cliprgn.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/cliprgn.c b/reactos/subsystems/win32/win32k/objects/cliprgn.c index 95e0e5cced9..7294f2b31fd 100644 --- a/reactos/subsystems/win32/win32k/objects/cliprgn.c +++ b/reactos/subsystems/win32/win32k/objects/cliprgn.c @@ -26,20 +26,13 @@ int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc) { PROSRGNDATA CombinedRegion; - HRGN hRgnVis = Dc->prgnVis->BaseObject.hHmgr; + HRGN hRgnVis; // would prefer this, but the rest of the code sucks // ASSERT(Dc->rosdc.hGCClipRgn); // ASSERT(Dc->rosdc.hClipRgn); - if (!Dc->prgnVis) - { - DPRINT1("Warning, prgnVis is NULL!\n"); - } - else - { - hRgnVis = Dc->prgnVis->BaseObject.hHmgr ; - } - + ASSERT(Dc->prgnVis); + hRgnVis = Dc->prgnVis->BaseObject.hHmgr; if (Dc->rosdc.hGCClipRgn == NULL) Dc->rosdc.hGCClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); From a3c683546ccdd935f6461f0ecccafc8193073685 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Wed, 23 Mar 2011 20:36:25 +0000 Subject: [PATCH 67/90] [DDK] Add most of RtlString***W functions based on ANSI versions. svn path=/trunk/; revision=51130 --- reactos/include/ddk/ntstrsafe.h | 249 +++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 5 deletions(-) diff --git a/reactos/include/ddk/ntstrsafe.h b/reactos/include/ddk/ntstrsafe.h index c107a0da425..055d3b312d2 100644 --- a/reactos/include/ddk/ntstrsafe.h +++ b/reactos/include/ddk/ntstrsafe.h @@ -17,6 +17,7 @@ #include #include #include +#include /* we need DWORD */ // // Maximum limits: allow overriding the maximum @@ -26,11 +27,6 @@ #endif #define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1) -// -// Typedefs -// -typedef unsigned long DWORD; - /* PRIVATE FUNCTIONS *********************************************************/ static __inline @@ -66,6 +62,39 @@ RtlStringLengthWorkerA(IN LPCSTR String, return Status; } +static __inline +NTSTATUS +NTAPI +RtlStringLengthWorkerW(IN LPCWSTR String, + IN SIZE_T MaxLength, + OUT PSIZE_T ReturnLength OPTIONAL) +{ + NTSTATUS Status = STATUS_SUCCESS; + SIZE_T LocalMax = MaxLength; + + while (MaxLength && (*String != UNICODE_NULL)) + { + String++; + MaxLength--; + } + + if (!MaxLength) Status = STATUS_INVALID_PARAMETER; + + if (ReturnLength) + { + if (NT_SUCCESS(Status)) + { + *ReturnLength = LocalMax - MaxLength; + } + else + { + *ReturnLength = 0; + } + } + + return Status; +} + static __inline NTSTATUS NTAPI @@ -95,6 +124,35 @@ RtlStringValidateDestA(IN LPSTR Destination, return Status; } +static __inline +NTSTATUS +NTAPI +RtlStringValidateDestW(IN LPWSTR Destination, + IN SIZE_T Length, + OUT PSIZE_T ReturnLength OPTIONAL, + IN SIZE_T MaxLength) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (!(Length) || (Length > MaxLength)) Status = STATUS_INVALID_PARAMETER; + + if (ReturnLength) + { + if (NT_SUCCESS(Status)) + { + Status = RtlStringLengthWorkerW(Destination, + Length, + ReturnLength); + } + else + { + *ReturnLength = 0; + } + } + + return Status; +} + static __inline NTSTATUS NTAPI @@ -111,6 +169,22 @@ RtlStringExValidateDestA(IN OUT LPSTR *Destination, MaxLength); } +static __inline +NTSTATUS +NTAPI +RtlStringExValidateDestW(IN OUT LPWSTR *Destination, + IN OUT PSIZE_T DestinationLength, + OUT PSIZE_T ReturnLength OPTIONAL, + IN SIZE_T MaxLength, + IN DWORD Flags) +{ + ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); + return RtlStringValidateDestW(*Destination, + *DestinationLength, + ReturnLength, + MaxLength); +} + static __inline NTSTATUS NTAPI @@ -130,6 +204,25 @@ RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL, return Status; } +static __inline +NTSTATUS +NTAPI +RtlStringExValidateSrcW(IN OUT LPCWSTR *Source OPTIONAL, + IN OUT PSIZE_T ReturnLength OPTIONAL, + IN SIZE_T MaxLength, + IN DWORD Flags) +{ + NTSTATUS Status = STATUS_SUCCESS; + ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); + + if ((ReturnLength) && (*ReturnLength >= MaxLength)) + { + Status = STATUS_INVALID_PARAMETER; + } + + return Status; +} + static __inline NTSTATUS NTAPI @@ -206,6 +299,41 @@ RtlStringCopyWorkerA(OUT LPSTR Destination, return Status; } +static __inline +NTSTATUS +NTAPI +RtlStringCopyWorkerW(OUT LPWSTR Destination, + IN SIZE_T Length, + OUT PSIZE_T NewLength OPTIONAL, + IN LPCWSTR Source, + IN SIZE_T CopyLength) +{ + NTSTATUS Status = STATUS_SUCCESS; + SIZE_T LocalNewLength = 0; + + while ((Length) && (CopyLength) && (*Source != UNICODE_NULL)) + { + *Destination++ = *Source++; + Length--; + CopyLength--; + + LocalNewLength++; + } + + if (!Length) + { + Destination--; + LocalNewLength--; + + Status = STATUS_BUFFER_OVERFLOW; + } + + *Destination = UNICODE_NULL; + + if (NewLength) *NewLength = LocalNewLength; + return Status; +} + /* PUBLIC FUNCTIONS **********************************************************/ static __inline @@ -219,6 +347,17 @@ RtlStringCchCopyA(IN LPSTR Destination, return STATUS_NOT_IMPLEMENTED; } +static __inline +NTSTATUS +NTAPI +RtlStringCchCopyW(IN LPWSTR Destination, + IN SIZE_T cchDest, + IN LPCWSTR pszSrc) +{ + ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE); + return STATUS_NOT_IMPLEMENTED; +} + static __inline NTSTATUS RtlStringCbPrintfA(OUT LPSTR Destination, @@ -491,6 +630,80 @@ RtlStringCbCatExA(IN OUT LPSTR Destination, return Status; } +static __inline +NTSTATUS +NTAPI +RtlStringCbCatExW(IN OUT LPWSTR Destination, + IN SIZE_T Length, + IN LPCWSTR Source, + OUT LPWSTR *DestinationEnd OPTIONAL, + OUT PSIZE_T RemainingSize OPTIONAL, + IN DWORD Flags) +{ + NTSTATUS Status; + SIZE_T CharLength = Length / sizeof(WCHAR); + SIZE_T DestinationLength, Remaining, Copied = 0; + PWCHAR LocalDestinationEnd; + ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); + + Status = RtlStringExValidateDestW(&Destination, + &CharLength, + &DestinationLength, + NTSTRSAFE_MAX_CCH, + Flags); + if (NT_SUCCESS(Status)) + { + LocalDestinationEnd = Destination + DestinationLength; + Remaining = CharLength - DestinationLength; + + Status = RtlStringExValidateSrcW(&Source, + NULL, + NTSTRSAFE_MAX_CCH, + Flags); + if (NT_SUCCESS(Status)) + { + if (Remaining <= 1) + { + if (*Source != UNICODE_NULL) + { + if (!Destination) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + Status = RtlStringCopyWorkerW(LocalDestinationEnd, + Remaining, + &Copied, + Source, + NTSTRSAFE_MAX_LENGTH); + + LocalDestinationEnd = LocalDestinationEnd + Copied; + Remaining = Remaining - Copied; + } + } + + if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) + { + if (DestinationEnd) *DestinationEnd = LocalDestinationEnd; + + if (RemainingSize) + { + *RemainingSize = (Remaining * sizeof(WCHAR)) + + (Length % sizeof(WCHAR)); + } + } + } + + return Status; +} + static __inline NTSTATUS NTAPI @@ -517,4 +730,30 @@ RtlStringCbCopyA(OUT LPSTR Destination, return Status; } +static __inline +NTSTATUS +NTAPI +RtlStringCbCopyW(OUT LPWSTR Destination, + IN SIZE_T Length, + IN LPCWSTR Source) +{ + NTSTATUS Status; + SIZE_T CharLength = Length / sizeof(WCHAR); + + Status = RtlStringValidateDestW(Destination, + CharLength, + NULL, + NTSTRSAFE_MAX_CCH); + if (NT_SUCCESS(Status)) + { + Status = RtlStringCopyWorkerW(Destination, + CharLength, + NULL, + Source, + NTSTRSAFE_MAX_LENGTH); + } + + return Status; +} + #endif /* _NTSTRSAFE_H_INCLUDED_ */ From 58789369ad64d30a2273c035538e06d0aa04d859 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Wed, 23 Mar 2011 20:48:20 +0000 Subject: [PATCH 68/90] Revert previous commit Sorry... I'll test first next time. svn path=/trunk/; revision=51131 --- reactos/include/ddk/ntstrsafe.h | 249 +------------------------------- 1 file changed, 5 insertions(+), 244 deletions(-) diff --git a/reactos/include/ddk/ntstrsafe.h b/reactos/include/ddk/ntstrsafe.h index 055d3b312d2..c107a0da425 100644 --- a/reactos/include/ddk/ntstrsafe.h +++ b/reactos/include/ddk/ntstrsafe.h @@ -17,7 +17,6 @@ #include #include #include -#include /* we need DWORD */ // // Maximum limits: allow overriding the maximum @@ -27,6 +26,11 @@ #endif #define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1) +// +// Typedefs +// +typedef unsigned long DWORD; + /* PRIVATE FUNCTIONS *********************************************************/ static __inline @@ -62,39 +66,6 @@ RtlStringLengthWorkerA(IN LPCSTR String, return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringLengthWorkerW(IN LPCWSTR String, - IN SIZE_T MaxLength, - OUT PSIZE_T ReturnLength OPTIONAL) -{ - NTSTATUS Status = STATUS_SUCCESS; - SIZE_T LocalMax = MaxLength; - - while (MaxLength && (*String != UNICODE_NULL)) - { - String++; - MaxLength--; - } - - if (!MaxLength) Status = STATUS_INVALID_PARAMETER; - - if (ReturnLength) - { - if (NT_SUCCESS(Status)) - { - *ReturnLength = LocalMax - MaxLength; - } - else - { - *ReturnLength = 0; - } - } - - return Status; -} - static __inline NTSTATUS NTAPI @@ -124,35 +95,6 @@ RtlStringValidateDestA(IN LPSTR Destination, return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringValidateDestW(IN LPWSTR Destination, - IN SIZE_T Length, - OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength) -{ - NTSTATUS Status = STATUS_SUCCESS; - - if (!(Length) || (Length > MaxLength)) Status = STATUS_INVALID_PARAMETER; - - if (ReturnLength) - { - if (NT_SUCCESS(Status)) - { - Status = RtlStringLengthWorkerW(Destination, - Length, - ReturnLength); - } - else - { - *ReturnLength = 0; - } - } - - return Status; -} - static __inline NTSTATUS NTAPI @@ -169,22 +111,6 @@ RtlStringExValidateDestA(IN OUT LPSTR *Destination, MaxLength); } -static __inline -NTSTATUS -NTAPI -RtlStringExValidateDestW(IN OUT LPWSTR *Destination, - IN OUT PSIZE_T DestinationLength, - OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength, - IN DWORD Flags) -{ - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - return RtlStringValidateDestW(*Destination, - *DestinationLength, - ReturnLength, - MaxLength); -} - static __inline NTSTATUS NTAPI @@ -204,25 +130,6 @@ RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL, return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringExValidateSrcW(IN OUT LPCWSTR *Source OPTIONAL, - IN OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength, - IN DWORD Flags) -{ - NTSTATUS Status = STATUS_SUCCESS; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - - if ((ReturnLength) && (*ReturnLength >= MaxLength)) - { - Status = STATUS_INVALID_PARAMETER; - } - - return Status; -} - static __inline NTSTATUS NTAPI @@ -299,41 +206,6 @@ RtlStringCopyWorkerA(OUT LPSTR Destination, return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCopyWorkerW(OUT LPWSTR Destination, - IN SIZE_T Length, - OUT PSIZE_T NewLength OPTIONAL, - IN LPCWSTR Source, - IN SIZE_T CopyLength) -{ - NTSTATUS Status = STATUS_SUCCESS; - SIZE_T LocalNewLength = 0; - - while ((Length) && (CopyLength) && (*Source != UNICODE_NULL)) - { - *Destination++ = *Source++; - Length--; - CopyLength--; - - LocalNewLength++; - } - - if (!Length) - { - Destination--; - LocalNewLength--; - - Status = STATUS_BUFFER_OVERFLOW; - } - - *Destination = UNICODE_NULL; - - if (NewLength) *NewLength = LocalNewLength; - return Status; -} - /* PUBLIC FUNCTIONS **********************************************************/ static __inline @@ -347,17 +219,6 @@ RtlStringCchCopyA(IN LPSTR Destination, return STATUS_NOT_IMPLEMENTED; } -static __inline -NTSTATUS -NTAPI -RtlStringCchCopyW(IN LPWSTR Destination, - IN SIZE_T cchDest, - IN LPCWSTR pszSrc) -{ - ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE); - return STATUS_NOT_IMPLEMENTED; -} - static __inline NTSTATUS RtlStringCbPrintfA(OUT LPSTR Destination, @@ -630,80 +491,6 @@ RtlStringCbCatExA(IN OUT LPSTR Destination, return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCbCatExW(IN OUT LPWSTR Destination, - IN SIZE_T Length, - IN LPCWSTR Source, - OUT LPWSTR *DestinationEnd OPTIONAL, - OUT PSIZE_T RemainingSize OPTIONAL, - IN DWORD Flags) -{ - NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(WCHAR); - SIZE_T DestinationLength, Remaining, Copied = 0; - PWCHAR LocalDestinationEnd; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - - Status = RtlStringExValidateDestW(&Destination, - &CharLength, - &DestinationLength, - NTSTRSAFE_MAX_CCH, - Flags); - if (NT_SUCCESS(Status)) - { - LocalDestinationEnd = Destination + DestinationLength; - Remaining = CharLength - DestinationLength; - - Status = RtlStringExValidateSrcW(&Source, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); - if (NT_SUCCESS(Status)) - { - if (Remaining <= 1) - { - if (*Source != UNICODE_NULL) - { - if (!Destination) - { - Status = STATUS_INVALID_PARAMETER; - } - else - { - Status = STATUS_BUFFER_OVERFLOW; - } - } - } - else - { - Status = RtlStringCopyWorkerW(LocalDestinationEnd, - Remaining, - &Copied, - Source, - NTSTRSAFE_MAX_LENGTH); - - LocalDestinationEnd = LocalDestinationEnd + Copied; - Remaining = Remaining - Copied; - } - } - - if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) - { - if (DestinationEnd) *DestinationEnd = LocalDestinationEnd; - - if (RemainingSize) - { - *RemainingSize = (Remaining * sizeof(WCHAR)) + - (Length % sizeof(WCHAR)); - } - } - } - - return Status; -} - static __inline NTSTATUS NTAPI @@ -730,30 +517,4 @@ RtlStringCbCopyA(OUT LPSTR Destination, return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCbCopyW(OUT LPWSTR Destination, - IN SIZE_T Length, - IN LPCWSTR Source) -{ - NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(WCHAR); - - Status = RtlStringValidateDestW(Destination, - CharLength, - NULL, - NTSTRSAFE_MAX_CCH); - if (NT_SUCCESS(Status)) - { - Status = RtlStringCopyWorkerW(Destination, - CharLength, - NULL, - Source, - NTSTRSAFE_MAX_LENGTH); - } - - return Status; -} - #endif /* _NTSTRSAFE_H_INCLUDED_ */ From 70a12312e313edc77115f229cc3896815396c43b Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 23 Mar 2011 23:17:45 +0000 Subject: [PATCH 69/90] [BUILD] - Remove redundant -fms-extensions as we set it globally already. svn path=/trunk/; revision=51132 --- reactos/dll/win32/user32/user32.rbuild | 1 - reactos/drivers/storage/class/ramdisk/ramdisk.rbuild | 1 - reactos/drivers/video/videoprt/videoprt.rbuild | 1 - reactos/subsystems/win32/csrss/csrss.rbuild | 1 - reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild | 1 - reactos/subsystems/win32/win32k/win32k.rbuild | 1 - 6 files changed, 6 deletions(-) diff --git a/reactos/dll/win32/user32/user32.rbuild b/reactos/dll/win32/user32/user32.rbuild index 6a66156a7dd..c2e8315666d 100644 --- a/reactos/dll/win32/user32/user32.rbuild +++ b/reactos/dll/win32/user32/user32.rbuild @@ -12,7 +12,6 @@ win32ksys pseh ntdll - -fms-extensions user32.h diff --git a/reactos/drivers/storage/class/ramdisk/ramdisk.rbuild b/reactos/drivers/storage/class/ramdisk/ramdisk.rbuild index 7a326c6a798..f861502db18 100644 --- a/reactos/drivers/storage/class/ramdisk/ramdisk.rbuild +++ b/reactos/drivers/storage/class/ramdisk/ramdisk.rbuild @@ -6,5 +6,4 @@ hal ramdisk.c ramdisk.rc - -fms-extensions diff --git a/reactos/drivers/video/videoprt/videoprt.rbuild b/reactos/drivers/video/videoprt/videoprt.rbuild index 992c20f3473..33e85561e6e 100644 --- a/reactos/drivers/video/videoprt/videoprt.rbuild +++ b/reactos/drivers/video/videoprt/videoprt.rbuild @@ -5,7 +5,6 @@ . include - -fms-extensions ntoskrnl hal videoprt.h diff --git a/reactos/subsystems/win32/csrss/csrss.rbuild b/reactos/subsystems/win32/csrss/csrss.rbuild index 438b2e6574a..43f87773d8d 100644 --- a/reactos/subsystems/win32/csrss/csrss.rbuild +++ b/reactos/subsystems/win32/csrss/csrss.rbuild @@ -6,7 +6,6 @@ include include/reactos/subsys include/reactos/drivers - -fms-extensions nt ntdll csrsrv diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index d81443be413..d402dbb8427 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -7,7 +7,6 @@ include/reactos/subsys include/reactos/drivers . - -fms-extensions ntdll user32 gdi32 diff --git a/reactos/subsystems/win32/win32k/win32k.rbuild b/reactos/subsystems/win32/win32k/win32k.rbuild index fa51a09635a..c9cf0ad78cd 100644 --- a/reactos/subsystems/win32/win32k/win32k.rbuild +++ b/reactos/subsystems/win32/win32k/win32k.rbuild @@ -16,7 +16,6 @@ include include/reactos/subsys include/reactos/drivers - -fms-extensions /wd4276 From 855227336f79b52d62aba17bac2b01b245843a31 Mon Sep 17 00:00:00 2001 From: Gabriel Ilardi Date: Thu, 24 Mar 2011 08:34:49 +0000 Subject: [PATCH 70/90] [SHELL32] Italian & Spanish fixes + RunFileDlg translations svn path=/trunk/; revision=51133 --- reactos/dll/win32/shell32/lang/es-ES.rc | 14 ++++----- reactos/dll/win32/shell32/lang/it-IT.rc | 40 ++++++++++++------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/reactos/dll/win32/shell32/lang/es-ES.rc b/reactos/dll/win32/shell32/lang/es-ES.rc index 1b48d7953db..0bbfc4677c2 100644 --- a/reactos/dll/win32/shell32/lang/es-ES.rc +++ b/reactos/dll/win32/shell32/lang/es-ES.rc @@ -113,8 +113,8 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Mensaje" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Si", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Si &a todo", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Sí", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Sí &a todo", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&No", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Cancelar", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP ICON "", IDD_ICON, 10, 10, 16, 16 @@ -156,7 +156,7 @@ CAPTION "Ejecutar" FONT 8, "MS Shell Dlg" BEGIN ICON "", 12297, 7, 11, 18, 20, WS_VISIBLE - LTEXT "Introduzca el nombre de un programa, carpeta, documento o recurso de Internet, y ReactOS lo abrirá para usted.", 12289, 36, 11, 182, 24 + LTEXT "Introduzca el nombre de un programa, carpeta, documento o recurso de Internet y ReactOS lo abrirá para usted.", 12289, 36, 11, 182, 24 LTEXT "&Abrir:", 12305, 7, 39, 24, 10 CONTROL "", 12298, "COMBOBOX", WS_TABSTOP | WS_GROUP | WS_VSCROLL | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWN, 36, 37, 183, 100 DEFPUSHBUTTON "Aceptar", IDOK, 62, 63, 50, 14, WS_TABSTOP @@ -682,10 +682,10 @@ BEGIN IDS_LOGOFF_PROMPT "żDesea cerrar la sesión?" /* Run File dialog */ - IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" - IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" - IDS_RUNDLG_BROWSE_CAPTION "Browse" - IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + IDS_RUNDLG_ERROR "Imposible mostrar el diálogo Ejecutar (error interno)" + IDS_RUNDLG_BROWSE_ERROR "Imposible mostrar el diálogo Examinar (error interno)" + IDS_RUNDLG_BROWSE_CAPTION "Examinar" + IDS_RUNDLG_BROWSE_FILTER "Archivos ejecutables (*.exe)\0*.exe\0Todos los archivos (*.*)\0*.*\0" /* shell folder path default values */ IDS_PROGRAMS "Menú Inicio\\Programas" diff --git a/reactos/dll/win32/shell32/lang/it-IT.rc b/reactos/dll/win32/shell32/lang/it-IT.rc index 09251b6fc34..59d76488d56 100644 --- a/reactos/dll/win32/shell32/lang/it-IT.rc +++ b/reactos/dll/win32/shell32/lang/it-IT.rc @@ -111,8 +111,8 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Messaggi" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Si", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Si a &tutti", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Sě", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Sě a &tutti", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&No", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Annulla", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP ICON "", IDD_ICON, 10, 10, 16, 16 @@ -154,7 +154,7 @@ CAPTION "" FONT 8, "MS Shell Dlg" BEGIN ICON "", 12297, 7, 11, 18, 20, WS_VISIBLE - LTEXT "Digitare il nome del programma, della cartella, del documento o della risorsa internet, e ReactOS la aprirŕ.", 12289, 36, 11, 182, 18 + LTEXT "Digitare il nome del programma, della cartella, del documento o della risorsa Internet, e ReactOS la aprirŕ.", 12289, 36, 11, 182, 18 LTEXT "&Apri:", 12305, 7, 39, 24, 10 CONTROL "", 12298, "COMBOBOX", WS_TABSTOP | WS_GROUP | WS_VSCROLL | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWN, 36, 37, 183, 100 DEFPUSHBUTTON "OK", IDOK, 62, 63, 50, 14, WS_TABSTOP @@ -297,7 +297,7 @@ BEGIN LTEXT "Disco %s", 14009, 100, 170, 40, 10 PUSHBUTTON "Pulitura disco", 14010, 180, 175, 50, 15, WS_TABSTOP CHECKBOX "Comprimere il disco per recuperare dello spazio", 14011, 15, 205, 180, 10, WS_DISABLED - CHECKBOX "Permettere di indicizzare questo disco al servizio di indicizzazione per avere ricerche dei file piů rapide", 14012, 15, 220, 200, 10, WS_DISABLED + CHECKBOX "Indicizza il disco per ricerche piů rapide dei file", 14012, 15, 220, 200, 10, WS_DISABLED END DRIVE_EXTRA_DLG DIALOGEX 0, 0, 240, 230 @@ -445,7 +445,7 @@ CAPTION "Conferma della sovrascrittura dei file" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "&Sě", IDYES, 20, 122, 60, 14 - PUSHBUTTON "Sě &tutti", 12807, 85, 122, 60, 14 + PUSHBUTTON "Sě a &tutti", 12807, 85, 122, 60, 14 PUSHBUTTON "&No", IDNO, 150, 122, 60, 14 PUSHBUTTON "Annulla", IDCANCEL, 215, 122, 60, 14 ICON 146, -1, 11, 10, 21, 20, SS_REALSIZECONTROL @@ -466,7 +466,7 @@ CAPTION "Chiudi sessione di ReactOS" FONT 8, "MS Shell Dlg" BEGIN ICON 45, 14344, 10, 10, 21, 20, SS_REALSIZECONTROL - LTEXT "Siete sicuro di voler Chiudere la sessione?", -1, 43, 11, 140, 22 + LTEXT "Siete sicuro di voler chiudere la sessione?", -1, 43, 11, 140, 22 DEFPUSHBUTTON "&Chiudi sessione", IDOK, 57, 40, 60, 14 PUSHBUTTON "Annulla", IDCANCEL, 122, 40, 60, 14 END @@ -583,7 +583,7 @@ BEGIN GROUPBOX "Opzioni per la verifica del disco", -1, 7, 6, 179, 50 PUSHBUTTON "Annulla", IDCANCEL, 118, 100, 60, 14 AUTOCHECKBOX "Correggi automaticamente gli errori", 14000, 16, 15, 155, 10 - AUTOCHECKBOX "&Ricerca dei settori difettosi e tentativo di correzione", 14001, 16, 30, 165, 10 + AUTOCHECKBOX "&Cerca i settori difettosi e tenta di correggerli", 14001, 16, 30, 165, 10 CONTROL "", 14002, "MSCTLS_PROGRESS32", 16, 7, 60, 170, 8 LTEXT "", 14003, 60, 80, 170, 10 END @@ -680,10 +680,10 @@ BEGIN IDS_LOGOFF_PROMPT "Volete disconnettervi?" /* Run File dialog */ - IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" - IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" - IDS_RUNDLG_BROWSE_CAPTION "Browse" - IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + IDS_RUNDLG_ERROR "Impossibile mostrare il dialogo Eseguire (errore interno)" + IDS_RUNDLG_BROWSE_ERROR "Impossibile mostrare il dialogo sfoglia (errore interno)" + IDS_RUNDLG_BROWSE_CAPTION "Sfoglia" + IDS_RUNDLG_BROWSE_FILTER "File Eseguibili (*.exe)\0*.exe\0Tutti i file (*.*)\0*.*\0" /* shell folder path default values */ IDS_PROGRAMS "Menu Avvio\\Programmi" @@ -733,22 +733,22 @@ BEGIN IDS_RECYCLEBIN_LOCATION "Posizione del Cestino" IDS_RECYCLEBIN_DISKSPACE "Spazio disponibile" IDS_EMPTY_BITBUCKET "Svuota cestino" - IDS_PICK_ICON_TITLE "Scegliere un icona" - IDS_PICK_ICON_FILTER "Icone (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" - IDS_OPEN_WITH_FILTER "File eseguibili (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + IDS_PICK_ICON_TITLE "Scegliere un'icona" + IDS_PICK_ICON_FILTER "Icone (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0Tutti i file (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "File eseguibili (*.exe)\0*.exe\0Tutti i file (*.*)\0*.*\0" IDS_DIRECTORY "Cartella" - IDS_VIRTUAL_DRIVER "Virtual Device Driver" - IDS_BAT_FILE "ReactOS Batch File" - IDS_CMD_FILE "ReactOS Command Script" - IDS_COM_FILE "Applicazione Dos" + IDS_VIRTUAL_DRIVER "Driver di Periferica Virtuale" + IDS_BAT_FILE "File Batch ReactOS" + IDS_CMD_FILE "Script di comandi ReactOS" + IDS_COM_FILE "Applicazione DOS" IDS_CPL_FILE "Elemento del pannello di controllo" IDS_CUR_FILE "Cursore" IDS_DLL_FILE "Estensione di applicazione" - IDS_DRV_FILE "Device Driver" + IDS_DRV_FILE "Driver di periferica" IDS_EXE_FILE "Applicazione" IDS_FON_FILE "Font" IDS_TTF_FILE "TrueType Font" - IDS_HLP_FILE "Help File" + IDS_HLP_FILE "File della guida" IDS_INI_FILE "Impostazioni di configurazione" IDS_LNK_FILE "Collegamento" IDS_SYS_FILE "File di sistema" From e0191e8920fc70d341f0e9e35050edb173b13a58 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 21:42:48 +0000 Subject: [PATCH 71/90] [PSDK] Import strsafe.h from mingw-w64. It's more complete compared to our headers [DDK] Import ntstrsafe.h from mingw-w64 (converted from strsafe.h). It's more complete compared to our headers [NTOSKRNL] Use sizeof instead of magic numbers Let's use strsafe functions now instead of strncpy/wcsncpy, which doesn't always NULL terminate :) svn path=/trunk/; revision=51135 --- reactos/base/applications/notepad/notepad.h | 4 + reactos/include/ddk/ntstrsafe.h | 2377 ++++++++++++++--- reactos/include/psdk/strsafe.h | 2617 ++++++++++++++----- reactos/ntoskrnl/ex/init.c | 26 +- 4 files changed, 4001 insertions(+), 1023 deletions(-) diff --git a/reactos/base/applications/notepad/notepad.h b/reactos/base/applications/notepad/notepad.h index bc910ab275e..909eca20b56 100644 --- a/reactos/base/applications/notepad/notepad.h +++ b/reactos/base/applications/notepad/notepad.h @@ -1,3 +1,7 @@ +#ifndef STRSAFE_NO_DEPRECATE +#define STRSAFE_NO_DEPRECATE +#endif + #include #include #include diff --git a/reactos/include/ddk/ntstrsafe.h b/reactos/include/ddk/ntstrsafe.h index c107a0da425..d34b8896814 100644 --- a/reactos/include/ddk/ntstrsafe.h +++ b/reactos/include/ddk/ntstrsafe.h @@ -1,520 +1,2065 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: This file is in the public domain. - * FILE: include/ddk/ntstrsafe.h - * PURPOSE: Safe String Library for NT Code (Native/Kernel) - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ - -/* INCLUDES ******************************************************************/ - #ifndef _NTSTRSAFE_H_INCLUDED_ #define _NTSTRSAFE_H_INCLUDED_ -// -// Dependencies -// #include #include #include -// -// Maximum limits: allow overriding the maximum -// -#ifndef NTSTRSAFE_MAX_CCH -#define NTSTRSAFE_MAX_CCH 2147483647 +#ifndef C_ASSERT +#ifdef _MSC_VER +# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] +#else +# define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) #endif -#define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1) +#endif /* C_ASSERT */ -// -// Typedefs -// -typedef unsigned long DWORD; +#ifdef __cplusplus +#define _STRSAFE_EXTERN_C extern "C" +#else +#define _STRSAFE_EXTERN_C extern +#endif -/* PRIVATE FUNCTIONS *********************************************************/ +#define NTSTRSAFEAPI static __inline NTSTATUS NTAPI +#define NTSTRSAFE_INLINE_API static __inline NTSTATUS NTAPI -static __inline -NTSTATUS -NTAPI -RtlStringLengthWorkerA(IN LPCSTR String, - IN SIZE_T MaxLength, - OUT PSIZE_T ReturnLength OPTIONAL) +#ifndef NTSTRSAFE_MAX_CCH +#define NTSTRSAFE_MAX_CCH 2147483647 +#endif + +#ifndef _STRSAFE_H_INCLUDED_ +#define STRSAFE_IGNORE_NULLS 0x00000100 +#define STRSAFE_FILL_BEHIND_NULL 0x00000200 +#define STRSAFE_FILL_ON_FAILURE 0x00000400 +#define STRSAFE_NULL_ON_FAILURE 0x00000800 +#define STRSAFE_NO_TRUNCATION 0x00001000 +#define STRSAFE_IGNORE_NULL_UNICODE_STRINGS 0x00010000 +#define STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED 0x00020000 + +#define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION) +#define STRSAFE_UNICODE_STRING_VALID_FLAGS (STRSAFE_VALID_FLAGS | STRSAFE_IGNORE_NULL_UNICODE_STRINGS | STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED) + +#define STRSAFE_FILL_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL)) +#define STRSAFE_FAILURE_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_ON_FAILURE)) + +#define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)((dwFlags) & 0x000000FF)) +#endif + +typedef char *STRSAFE_LPSTR; +typedef const char *STRSAFE_LPCSTR; +typedef wchar_t *STRSAFE_LPWSTR; +typedef const wchar_t *STRSAFE_LPCWSTR; + +typedef ULONG STRSAFE_DWORD; + +NTSTRSAFEAPI RtlStringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); +NTSTRSAFEAPI RtlStringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy); +NTSTRSAFEAPI RtlStringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy); +NTSTRSAFEAPI RtlStringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); +NTSTRSAFEAPI RtlStringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend); +NTSTRSAFEAPI RtlStringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend); +NTSTRSAFEAPI RtlStringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength); +NTSTRSAFEAPI RtlStringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength); + +NTSTRSAFEAPI RtlStringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); + + +NTSTRSAFEAPI RtlStringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { - NTSTATUS Status = STATUS_SUCCESS; - SIZE_T LocalMax = MaxLength; + return (cchDest > NTSTRSAFE_MAX_CCH ? STATUS_INVALID_PARAMETER : RtlStringCopyWorkerA(pszDest,cchDest,pszSrc)); +} - while (MaxLength && (*String != ANSI_NULL)) +NTSTRSAFEAPI RtlStringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc); +} + + +NTSTRSAFEAPI RtlStringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc); + + +NTSTRSAFEAPI RtlStringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc) +{ + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyWorkerA(pszDest,cbDest,pszSrc); +} + +NTSTRSAFEAPI RtlStringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc); +} + + +NTSTRSAFEAPI RtlStringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + +NTSTRSAFEAPI RtlStringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + size_t cbDest; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + cbDest = cchDest * sizeof(wchar_t); + return RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + + +NTSTRSAFEAPI RtlStringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchRemaining = 0; + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + Status = RtlStringCopyExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) { - String++; - MaxLength--; + if (pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); } - - if (!MaxLength) Status = STATUS_INVALID_PARAMETER; - - if (ReturnLength) - { - if (NT_SUCCESS(Status)) - { - *ReturnLength = LocalMax - MaxLength; - } - else - { - *ReturnLength = 0; - } - } - return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringValidateDestA(IN LPSTR Destination, - IN SIZE_T Length, - OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength) +NTSTRSAFEAPI RtlStringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchRemaining = 0; - if (!(Length) || (Length > MaxLength)) Status = STATUS_INVALID_PARAMETER; - - if (ReturnLength) + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + Status = RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) { - if (NT_SUCCESS(Status)) - { - Status = RtlStringLengthWorkerA(Destination, - Length, - ReturnLength); - } - else - { - *ReturnLength = 0; - } + if (pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); } - return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringExValidateDestA(IN OUT LPSTR *Destination, - IN OUT PSIZE_T DestinationLength, - OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength, - IN DWORD Flags) + +NTSTRSAFEAPI RtlStringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy); +NTSTRSAFEAPI RtlStringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy); + + +NTSTRSAFEAPI RtlStringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy) { - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - return RtlStringValidateDestA(*Destination, - *DestinationLength, - ReturnLength, - MaxLength); + if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNWorkerA(pszDest,cchDest,pszSrc,cchToCopy); } -static __inline -NTSTATUS -NTAPI -RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL, - IN OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength, - IN DWORD Flags) +NTSTRSAFEAPI RtlStringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy) { - NTSTATUS Status = STATUS_SUCCESS; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); + if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy); +} - if ((ReturnLength) && (*ReturnLength >= MaxLength)) - { + +NTSTRSAFEAPI RtlStringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy); +NTSTRSAFEAPI RtlStringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy); + + +NTSTRSAFEAPI RtlStringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy) +{ + if (cbDest > NTSTRSAFE_MAX_CCH || cbToCopy > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNWorkerA(pszDest,cbDest,pszSrc,cbToCopy); +} + +NTSTRSAFEAPI RtlStringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy); +} + + +NTSTRSAFEAPI RtlStringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags); +} + +NTSTRSAFEAPI RtlStringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNExWorkerW(pszDest,cchDest,cchDest * sizeof(wchar_t),pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags); +} + + +NTSTRSAFEAPI RtlStringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchRemaining = 0; + if (cbDest > NTSTRSAFE_MAX_CCH) Status = STATUS_INVALID_PARAMETER; - } - + else + Status = RtlStringCopyNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToCopy,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = cchRemaining; return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringVPrintfWorkerA(OUT LPSTR Destination, - IN SIZE_T Length, - OUT PSIZE_T NewLength OPTIONAL, - IN LPCSTR Format, - IN va_list argList) +NTSTRSAFEAPI RtlStringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { - NTSTATUS Status = STATUS_SUCCESS; - LONG Return; - SIZE_T MaxLength, LocalNewLength = 0; + NTSTATUS Status; + size_t cchDest; + size_t cchToCopy; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + cchToCopy = cbToCopy / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCopyNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToCopy,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return Status; +} - MaxLength = Length - 1; - Return = _vsnprintf(Destination, MaxLength, Format, argList); - if ((Return < 0) || ((SIZE_T)Return > MaxLength)) - { - Destination += MaxLength; - *Destination = ANSI_NULL; +NTSTRSAFEAPI RtlStringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); - LocalNewLength = MaxLength; - Status = STATUS_BUFFER_OVERFLOW; - } - else if ((SIZE_T)Return == MaxLength) - { - Destination += MaxLength; - *Destination = ANSI_NULL; +NTSTRSAFEAPI RtlStringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatWorkerA(pszDest,cchDest,pszSrc); +} - LocalNewLength = MaxLength; - } +NTSTRSAFEAPI RtlStringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatWorkerW(pszDest,cchDest,pszSrc); +} + + +NTSTRSAFEAPI RtlStringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc); + + +NTSTRSAFEAPI RtlStringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc) +{ + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatWorkerA(pszDest,cbDest,pszSrc); +} + +NTSTRSAFEAPI RtlStringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatWorkerW(pszDest,cchDest,pszSrc); +} + + +NTSTRSAFEAPI RtlStringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + +NTSTRSAFEAPI RtlStringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + size_t cbDest = cchDest*sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + + +NTSTRSAFEAPI RtlStringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchRemaining = 0; + if (cbDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCatExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + return Status; +} + +NTSTRSAFEAPI RtlStringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchRemaining = 0; + + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return Status; +} + + +NTSTRSAFEAPI RtlStringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend); +NTSTRSAFEAPI RtlStringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend); + + +NTSTRSAFEAPI RtlStringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNWorkerA(pszDest,cchDest,pszSrc,cchToAppend); +} + +NTSTRSAFEAPI RtlStringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend); +} + + +NTSTRSAFEAPI RtlStringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend); +NTSTRSAFEAPI RtlStringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend); + + +NTSTRSAFEAPI RtlStringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend) +{ + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNWorkerA(pszDest,cbDest,pszSrc,cbToAppend); +} + +NTSTRSAFEAPI RtlStringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend); +} + + +NTSTRSAFEAPI RtlStringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags); +} + +NTSTRSAFEAPI RtlStringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNExWorkerW(pszDest,cchDest,(cchDest*sizeof(wchar_t)),pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags); +} + + +NTSTRSAFEAPI RtlStringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchRemaining = 0; + if (cbDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCatNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToAppend,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + return Status; +} + +NTSTRSAFEAPI RtlStringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + size_t cchRemaining = 0; + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCatNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToAppend,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return Status; +} + + +NTSTRSAFEAPI RtlStringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList); + + +NTSTRSAFEAPI RtlStringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList); +} + +NTSTRSAFEAPI RtlStringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); +} + + +NTSTRSAFEAPI RtlStringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList); + + +NTSTRSAFEAPI RtlStringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList); +} + +NTSTRSAFEAPI RtlStringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); +} + + +NTSTRSAFEAPI RtlStringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...); +NTSTRSAFEAPI RtlStringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...); + + +NTSTRSAFEAPI RtlStringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return Status; +} + +NTSTRSAFEAPI RtlStringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return Status; +} + + +NTSTRSAFEAPI RtlStringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...); +NTSTRSAFEAPI RtlStringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...); + + +NTSTRSAFEAPI RtlStringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList); + va_end(argList); + return Status; +} + +NTSTRSAFEAPI RtlStringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + size_t cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return Status; +} + + +NTSTRSAFEAPI RtlStringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...); +NTSTRSAFEAPI RtlStringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...); + + +NTSTRSAFEAPI RtlStringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cchDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + return Status; +} + +NTSTRSAFEAPI RtlStringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...) +{ + NTSTATUS Status; + size_t cbDest = cchDest * sizeof(wchar_t); + va_list argList; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + return Status; +} + + +NTSTRSAFEAPI RtlStringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...); +NTSTRSAFEAPI RtlStringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...); + + +NTSTRSAFEAPI RtlStringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...) +{ + NTSTATUS Status; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; else { - LocalNewLength = Return; - } - - if (NewLength) *NewLength = LocalNewLength; - return Status; -} - -static __inline -NTSTATUS -NTAPI -RtlStringCopyWorkerA(OUT LPSTR Destination, - IN SIZE_T Length, - OUT PSIZE_T NewLength OPTIONAL, - IN LPCSTR Source, - IN SIZE_T CopyLength) -{ - NTSTATUS Status = STATUS_SUCCESS; - SIZE_T LocalNewLength = 0; - - while ((Length) && (CopyLength) && (*Source != ANSI_NULL)) - { - *Destination++ = *Source++; - Length--; - CopyLength--; - - LocalNewLength++; - } - - if (!Length) - { - Destination--; - LocalNewLength--; - - Status = STATUS_BUFFER_OVERFLOW; - } - - *Destination = ANSI_NULL; - - if (NewLength) *NewLength = LocalNewLength; - return Status; -} - -/* PUBLIC FUNCTIONS **********************************************************/ - -static __inline -NTSTATUS -NTAPI -RtlStringCchCopyA(IN LPSTR Destination, - IN SIZE_T cchDest, - IN LPCSTR pszSrc) -{ - ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE); - return STATUS_NOT_IMPLEMENTED; -} - -static __inline -NTSTATUS -RtlStringCbPrintfA(OUT LPSTR Destination, - IN SIZE_T Length, - IN LPCSTR Format, - ...) -{ - NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR); - va_list argList; - - Status = RtlStringValidateDestA(Destination, - CharLength, - NULL, - NTSTRSAFE_MAX_CCH); - if (NT_SUCCESS(Status)) - { - va_start(argList, Format); - Status = RtlStringVPrintfWorkerA(Destination, - CharLength, - NULL, - Format, - argList); + va_list argList; + va_start(argList,pszFormat); + Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); va_end(argList); } - + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (pcbRemaining) + { + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + } + } return Status; } -static __inline -NTSTATUS -RtlStringCbPrintfExA(OUT LPSTR Destination, - IN SIZE_T Length, - OUT LPSTR *DestinationEnd OPTIONAL, - OUT PSIZE_T RemainingSize OPTIONAL, - IN DWORD Flags, - IN LPCSTR Format, - ...) +NTSTRSAFEAPI RtlStringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...) { NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR), Remaining, LocalNewLength = 0; - PCHAR LocalDestinationEnd; - va_list argList; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - - Status = RtlStringExValidateDestA(&Destination, - &CharLength, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); - if (NT_SUCCESS(Status)) + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else { - LocalDestinationEnd = Destination; - Remaining = CharLength; + va_list argList; + va_start(argList,pszFormat); + Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (pcbRemaining) + { + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + return Status; +} - Status = RtlStringExValidateSrcA(&Format, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); + +NTSTRSAFEAPI RtlStringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); + + +NTSTRSAFEAPI RtlStringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + NTSTATUS Status; + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + size_t cbDest; + cbDest = cchDest*sizeof(char); + Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + } + return Status; +} + +NTSTRSAFEAPI RtlStringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + NTSTATUS Status; + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + size_t cbDest; + cbDest = cchDest*sizeof(wchar_t); + Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + } + return Status; +} + + +NTSTRSAFEAPI RtlStringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); + + +NTSTRSAFEAPI RtlStringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + NTSTATUS Status; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (pcbRemaining) + { + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + } + } + return Status; +} + +NTSTRSAFEAPI RtlStringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + NTSTATUS Status; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (pcbRemaining) + { + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + return Status; +} + + +NTSTRSAFEAPI RtlStringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength); +NTSTRSAFEAPI RtlStringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength); + + +NTSTRSAFEAPI RtlStringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength) +{ + NTSTATUS Status; + if (!psz || (cchMax > NTSTRSAFE_MAX_CCH)) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringLengthWorkerA(psz,cchMax,pcchLength); + if (!NT_SUCCESS(Status) && pcchLength) + { + *pcchLength = 0; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength) +{ + NTSTATUS Status; + if (!psz || (cchMax > NTSTRSAFE_MAX_CCH)) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringLengthWorkerW(psz,cchMax,pcchLength); + if (!NT_SUCCESS(Status) && pcchLength) + { + *pcchLength = 0; + } + return Status; +} + + +NTSTRSAFEAPI RtlStringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength); +NTSTRSAFEAPI RtlStringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength); + + +NTSTRSAFEAPI RtlStringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength) +{ + NTSTATUS Status; + size_t cchMax; + size_t cchLength = 0; + cchMax = cbMax / sizeof(char); + if (!psz || (cchMax > NTSTRSAFE_MAX_CCH)) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringLengthWorkerA(psz,cchMax,&cchLength); + if (pcbLength) + { if (NT_SUCCESS(Status)) { - if (!Length) - { - if (*Format != ANSI_NULL) - { - if (!Destination) - { - Status = STATUS_INVALID_PARAMETER; - } - else - { - Status = STATUS_BUFFER_OVERFLOW; - } - } - } - else - { - va_start(argList, Format); - Status = RtlStringVPrintfWorkerA(Destination, - CharLength, - &LocalNewLength, - Format, - argList); - va_end(argList); - - LocalDestinationEnd = Destination + LocalNewLength; - Remaining = CharLength - LocalNewLength; - } + *pcbLength = cchLength*sizeof(char); } else { - if (Length) *Destination = ANSI_NULL; - } - - if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) - { - if (DestinationEnd) *DestinationEnd = LocalDestinationEnd; - - if (RemainingSize) - { - *RemainingSize = (Remaining * sizeof(CHAR)) + - (Length % sizeof(CHAR)); - } + *pcbLength = 0; } } - return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCbCopyExA(OUT LPSTR Destination, - IN SIZE_T Length, - IN LPCSTR Source, - OUT LPSTR *DestinationEnd OPTIONAL, - OUT PSIZE_T RemainingSize OPTIONAL, - IN DWORD Flags) +NTSTRSAFEAPI RtlStringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength) { NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR), Copied = 0, Remaining; - PCHAR LocalDestinationEnd; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - - Status = RtlStringExValidateDestA(&Destination, - &Length, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); - if (NT_SUCCESS(Status)) + size_t cchMax; + size_t cchLength = 0; + cchMax = cbMax / sizeof(wchar_t); + if (!psz || (cchMax > NTSTRSAFE_MAX_CCH)) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringLengthWorkerW(psz,cchMax,&cchLength); + if (pcbLength) { - LocalDestinationEnd = Destination; - Remaining = CharLength; - - Status = RtlStringExValidateSrcA(&Source, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); if (NT_SUCCESS(Status)) { - if (!CharLength) - { - if (*Source != ANSI_NULL) - { - if (!Destination) - { - Status = STATUS_INVALID_PARAMETER; - } - else - { - Status = STATUS_BUFFER_OVERFLOW; - } - } - } - else - { - Status = RtlStringCopyWorkerA(Destination, - CharLength, - &Copied, - Source, - NTSTRSAFE_MAX_LENGTH); - - LocalDestinationEnd = Destination + Copied; - Remaining = CharLength - Copied; - } + *pcbLength = cchLength*sizeof(wchar_t); } else { - if (CharLength) *Destination = ANSI_NULL; - } - - if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) - { - if (DestinationEnd) *DestinationEnd = LocalDestinationEnd; - - if (RemainingSize) - { - *RemainingSize = (Remaining * sizeof(CHAR)) + - (Length % sizeof(CHAR)); - } + *pcbLength = 0; } } - return Status; } -static __inline -NTSTATUS -RtlStringCbPrintfW( - LPWSTR pszDest, - IN size_t cbDest, - IN LPCWSTR pszFormat, - ...) +NTSTRSAFEAPI RtlStringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { - ASSERTMSG("RtlStringCbPrintfW is UNIMPLEMENTED!\n", FALSE); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + while(cchDest && (*pszSrc!='\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + } + if (cchDest==0) + { + pszDest--; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDest= '\0'; + } + return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCbCatExA(IN OUT LPSTR Destination, - IN SIZE_T Length, - IN LPCSTR Source, - OUT LPSTR *DestinationEnd OPTIONAL, - OUT PSIZE_T RemainingSize OPTIONAL, - IN DWORD Flags) +NTSTRSAFEAPI RtlStringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { - NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR); - SIZE_T DestinationLength, Remaining, Copied = 0; - PCHAR LocalDestinationEnd; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - - Status = RtlStringExValidateDestA(&Destination, - &CharLength, - &DestinationLength, - NTSTRSAFE_MAX_CCH, - Flags); - if (NT_SUCCESS(Status)) + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else { - LocalDestinationEnd = Destination + DestinationLength; - Remaining = CharLength - DestinationLength; + while(cchDest && (*pszSrc!=L'\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + } + if (cchDest==0) + { + pszDest--; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDest= L'\0'; + } + return Status; +} - Status = RtlStringExValidateSrcA(&Source, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); +NTSTRSAFEAPI RtlStringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszSrc) + pszSrc = ""; + } if (NT_SUCCESS(Status)) { - if (Remaining <= 1) + if (cchDest==0) { - if (*Source != ANSI_NULL) + pszDestEnd = pszDest; + cchRemaining = 0; + if (*pszSrc!='\0') { - if (!Destination) - { + if (!pszDest) Status = STATUS_INVALID_PARAMETER; - } else - { Status = STATUS_BUFFER_OVERFLOW; - } } } else { - Status = RtlStringCopyWorkerA(LocalDestinationEnd, - Remaining, - &Copied, - Source, - NTSTRSAFE_MAX_LENGTH); - - LocalDestinationEnd = LocalDestinationEnd + Copied; - Remaining = Remaining - Copied; - } - } - - if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) - { - if (DestinationEnd) *DestinationEnd = LocalDestinationEnd; - - if (RemainingSize) - { - *RemainingSize = (Remaining * sizeof(CHAR)) + - (Length % sizeof(CHAR)); + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && (*pszSrc!='\0')) + { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + } + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + else + { + pszDestEnd--; + cchRemaining++; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDestEnd = '\0'; } } } - + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCbCopyA(OUT LPSTR Destination, - IN SIZE_T Length, - IN LPCSTR Source) +NTSTRSAFEAPI RtlStringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszSrc) + pszSrc = L""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if (*pszSrc!=L'\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && (*pszSrc!=L'\0')) + { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + } + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + else + { + pszDestEnd--; + cchRemaining++; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDestEnd = L'\0'; + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchSrc) +{ + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + while(cchDest && cchSrc && (*pszSrc!='\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchSrc--; + } + if (cchDest==0) + { + pszDest--; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDest= '\0'; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy) +{ + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + while(cchDest && cchToCopy && (*pszSrc!=L'\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchToCopy--; + } + if (cchDest==0) + { + pszDest--; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDest= L'\0'; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + if (cchToCopy > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszSrc) + pszSrc = ""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if ((cchToCopy!=0) && (*pszSrc!='\0')) + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && cchToCopy && (*pszSrc!='\0')) + { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + cchToCopy--; + } + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + else + { + pszDestEnd--; + cchRemaining++; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDestEnd = '\0'; + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + if (cchToCopy > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszSrc) + pszSrc = L""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if ((cchToCopy!=0) && (*pszSrc!=L'\0')) + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && cchToCopy && (*pszSrc!=L'\0')) + { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + cchToCopy--; + } + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + else + { + pszDestEnd--; + cchRemaining++; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDestEnd = L'\0'; + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR); - - Status = RtlStringValidateDestA(Destination, - CharLength, - NULL, - NTSTRSAFE_MAX_CCH); + size_t cchDestLength; + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); if (NT_SUCCESS(Status)) - { - Status = RtlStringCopyWorkerA(Destination, - CharLength, - NULL, - Source, - NTSTRSAFE_MAX_LENGTH); - } - + Status = RtlStringCopyWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc); return Status; } -#endif /* _NTSTRSAFE_H_INCLUDED_ */ +NTSTRSAFEAPI RtlStringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) +{ + NTSTATUS Status; + size_t cchDestLength; + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + Status = RtlStringCopyWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc); + return Status; +} + +NTSTRSAFEAPI RtlStringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + size_t cchDestLength; + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest==0) && (cbDest==0)) + cchDestLength = 0; + else + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (!pszSrc) + pszSrc = ""; + } + else + { + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + if (*pszSrc!='\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + Status = RtlStringCopyExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & STRSAFE_NULL_ON_FAILURE) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + size_t cchDestLength; + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest==0) && (cbDest==0)) + cchDestLength = 0; + else + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (!pszSrc) + pszSrc = L""; + } + else + { + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + if (*pszSrc!=L'\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + Status = RtlStringCopyExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & STRSAFE_NULL_ON_FAILURE) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend) +{ + NTSTATUS Status; + size_t cchDestLength; + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + Status = RtlStringCopyNWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend); + return Status; +} + +NTSTRSAFEAPI RtlStringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend) +{ + NTSTATUS Status; + size_t cchDestLength; + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + Status = RtlStringCopyNWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend); + return Status; +} + +NTSTRSAFEAPI RtlStringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestLength = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + if (cchToAppend > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest==0) && (cbDest==0)) + cchDestLength = 0; + else + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (!pszSrc) + pszSrc = ""; + } + else + { + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + if ((cchToAppend!=0) && (*pszSrc!='\0')) + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + Status = RtlStringCopyNExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestLength = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + if (cchToAppend > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest==0) && (cbDest==0)) + cchDestLength = 0; + else + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (!pszSrc) + pszSrc = L""; + } + else + { + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + if ((cchToAppend!=0) && (*pszSrc!=L'\0')) + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + Status = RtlStringCopyNExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList); + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + pszDest += cchMax; + *pszDest = '\0'; + Status = STATUS_BUFFER_OVERFLOW; + } + else + if (((size_t)iRet)==cchMax) + { + pszDest += cchMax; + *pszDest = '\0'; + } + } + return Status; +} + +NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList); + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + pszDest += cchMax; + *pszDest = L'\0'; + Status = STATUS_BUFFER_OVERFLOW; + } + else + if (((size_t)iRet)==cchMax) + { + pszDest += cchMax; + *pszDest = L'\0'; + } + } + return Status; +} + +NTSTRSAFEAPI RtlStringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszFormat) + pszFormat = ""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if (*pszFormat!='\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList); + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = '\0'; + Status = STATUS_BUFFER_OVERFLOW; + } + else + if (((size_t)iRet)==cchMax) + { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + else + if (((size_t)iRet) < cchMax) + { + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszFormat) + pszFormat = L""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if (*pszFormat!=L'\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList); + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = L'\0'; + Status = STATUS_BUFFER_OVERFLOW; + } + else + if (((size_t)iRet)==cchMax) + { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + else + if (((size_t)iRet) < cchMax) + { + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength) +{ + NTSTATUS Status = STATUS_SUCCESS; + size_t cchMaxPrev = cchMax; + while(cchMax && (*psz!='\0')) + { + psz++; + cchMax--; + } + if (cchMax==0) + Status = STATUS_INVALID_PARAMETER; + if (pcchLength) + { + if (NT_SUCCESS(Status)) + *pcchLength = cchMaxPrev - cchMax; + else + *pcchLength = 0; + } + return Status; +} + +NTSTRSAFEAPI RtlStringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength) +{ + NTSTATUS Status = STATUS_SUCCESS; + size_t cchMaxPrev = cchMax; + while(cchMax && (*psz!=L'\0')) + { + psz++; + cchMax--; + } + if (cchMax==0) + Status = STATUS_INVALID_PARAMETER; + if (pcchLength) + { + if (NT_SUCCESS(Status)) + *pcchLength = cchMaxPrev - cchMax; + else + *pcchLength = 0; + } + return Status; +} + + + +#define RtlStringCopyWorkerA RtlStringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define RtlStringCopyWorkerW RtlStringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define RtlStringCopyExWorkerA RtlStringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define RtlStringCopyExWorkerW RtlStringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define RtlStringCatWorkerA RtlStringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define RtlStringCatWorkerW RtlStringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define RtlStringCatExWorkerA RtlStringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define RtlStringCatExWorkerW RtlStringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define RtlStringCatNWorkerA RtlStringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA; +#define RtlStringCatNWorkerW RtlStringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW; +#define RtlStringCatNExWorkerA RtlStringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA; +#define RtlStringCatNExWorkerW RtlStringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW; +#define RtlStringVPrintfWorkerA RtlStringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define RtlStringVPrintfWorkerW RtlStringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define RtlStringVPrintfExWorkerA RtlStringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define RtlStringVPrintfExWorkerW RtlStringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define RtlStringLengthWorkerA RtlStringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA; +#define RtlStringLengthWorkerW RtlStringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW; + +#endif diff --git a/reactos/include/psdk/strsafe.h b/reactos/include/psdk/strsafe.h index 0f84a20dd77..f3f7eac7f21 100644 --- a/reactos/include/psdk/strsafe.h +++ b/reactos/include/psdk/strsafe.h @@ -1,631 +1,2062 @@ -#ifndef __STRSAFE_H_ -#define __STRSAFE_H_ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#ifndef _STRSAFE_H_INCLUDED_ +#define _STRSAFE_H_INCLUDED_ +#include <_mingw_unicode.h> #include -#include +#include #include +#include -#if defined(STRSAFE_NO_CCH_FUNCTIONS) && defined(STRSAFE_NO_CB_FUNCTIONS) -#error Both STRSAFE_NO_CCH_FUNCTIONS and STRSAFE_NO_CB_FUNCTIONS are defined +#ifndef _SIZE_T_DEFINED +#define _SIZE_T_DEFINED +#undef size_t +#ifdef _WIN64 +__MINGW_EXTENSION typedef unsigned __int64 size_t; +#else +typedef unsigned int size_t; +#endif #endif -#ifndef SUCCEEDED -#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0) +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 +__MINGW_EXTENSION typedef __int64 ssize_t; +#else +typedef int ssize_t; #endif -#define STRSAFE_MAX_CCH 2147483647 -#define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L) -#define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) -#define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L) - -#define STRSAFE_FILL_BEHIND_NULL 0x00000200 -#define STRSAFE_IGNORE_NULLS 0x00000200 -#define STRSAFE_FILL_ON_FAILURE 0x00000400 -#define STRSAFE_NULL_ON_FAILURE 0x00000800 -#define STRSAFE_NO_TRUNCATION 0x00001000 - -#ifndef S_OK -#define S_OK ((HRESULT)0x00000000L) #endif -#define STRSAFE_MIN(a,b) (((a) < (b))?(a):(b)) +#ifndef _WCHAR_T_DEFINED +#define _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +#endif #ifndef _HRESULT_DEFINED #define _HRESULT_DEFINED typedef long HRESULT; #endif -typedef char * STRSAFE_LPSTR; -typedef const char * STRSAFE_LPCSTR; -typedef wchar_t * STRSAFE_LPWSTR; -typedef const wchar_t * STRSAFE_LPCWSTR; -typedef unsigned long STRSAFE_DWORD; - -#define STRSAFE_PASS2 - -/* Implement Cb functions for ansi and unicode */ -#ifndef STRSAFE_NO_CB_FUNCTIONS -#define STRSAFE_CB -#define STRSAFE_UNICODE 0 -# include -#undef STRSAFE_UNICODE -#define STRSAFE_UNICODE 1 -# include -#undef STRSAFE_UNICODE -#undef STRSAFE_CB -#endif // !STRSAFE_NO_CB_FUNCTIONS - -/* Implement Cch functions for ansi and unicode */ -#ifndef STRSAFE_NO_CCH_FUNCTIONS -#define STRSAFE_UNICODE 0 -# include -#undef STRSAFE_UNICODE -#define STRSAFE_UNICODE 1 -# include -#undef STRSAFE_UNICODE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - -#undef STRSAFE_PASS2 - -/* Now define the functions depending on UNICODE */ -#if defined(UNICODE) -# define STRSAFE_UNICODE 1 -#else -# define STRSAFE_UNICODE 0 -#endif -#include -#undef STRSAFE_UNICODE - -#endif // !__STRSAFE_H_ - -/*****************************************************************************/ - -#if defined(STRSAFE_UNICODE) -#if (STRSAFE_UNICODE == 1) - -#define STRSAFE_LPTSTR STRSAFE_LPWSTR -#define STRSAFE_LPCTSTR STRSAFE_LPCWSTR -#define STRSAFE_TCHAR wchar_t - -#define StringCbCat StringCbCatW -#define StringCbCatEx StringCbCatExW -#define StringCbCatN StringCbCatNW -#define StringCbCatNEx StringCbCatNExW -#define StringCbCatWorker StringCxxCatWorkerW -#define StringCbCopy StringCbCopyW -#define StringCbCopyEx StringCbCopyExW -#define StringCbCopyN StringCbCopyNW -#define StringCbCopyNEx StringCbCopyNExW -#define StringCbGets StringCbGetsW -#define StringCbGetsEx StringCbGetsExW -#define StringCbLength StringCbLengthW -#define StringCbPrintf StringCbPrintfW -#define StringCbPrintfEx StringCbPrintfExW -#define StringCbVPrintf StringCbVPrintfW -#define StringCbVPrintfEx StringCbVPrintfExW -#define StringCchCat StringCchCatW -#define StringCchCatEx StringCchCatExW -#define StringCchCatN StringCchCatNW -#define StringCchCatNEx StringCchCatNExW -#define StringCchCatWorker StringCchCatWorkerW -#define StringCchCopy StringCchCopyW -#define StringCchCopyEx StringCchCopyExW -#define StringCchCopyN StringCchCopyNW -#define StringCchCopyNEx StringCchCopyNExW -#define StringCchGets StringCchGetsW -#define StringCchGetsEx StringCchGetsExW -#define StringCchLength StringCchLengthW -#define StringCchPrintf StringCchPrintfW -#define StringCchPrintfEx StringCchPrintfExW -#define StringCchVPrintf StringCchVPrintfW -#define StringCchVPrintfEx StringCchVPrintfExW -#define _vsnprintfAW _vsnwprintf - -#else // (STRSAFE_UNICODE != 1) - -#define STRSAFE_LPTSTR STRSAFE_LPSTR -#define STRSAFE_LPCTSTR STRSAFE_LPCSTR -#define STRSAFE_TCHAR char - -#define StringCbCat StringCbCatA -#define StringCbCatEx StringCbCatExA -#define StringCbCatN StringCbCatNA -#define StringCbCatNEx StringCbCatNExA -#define StringCbCatWorker StringCxxCatWorkerA -#define StringCbCopy StringCbCopyA -#define StringCbCopyEx StringCbCopyExA -#define StringCbCopyN StringCbCopyNA -#define StringCbCopyNEx StringCbCopyNExA -#define StringCbGets StringCbGetsA -#define StringCbGetsEx StringCbGetsExA -#define StringCbLength StringCbLengthA -#define StringCbPrintf StringCbPrintfA -#define StringCbPrintfEx StringCbPrintfExA -#define StringCbVPrintf StringCbVPrintfA -#define StringCbVPrintfEx StringCbVPrintfExA -#define StringCchCat StringCchCatA -#define StringCchCatEx StringCchCatExA -#define StringCchCatN StringCchCatNA -#define StringCchCatNEx StringCchCatNExA -#define StringCchCatWorker StringCchCatWorkerA -#define StringCchCopy StringCchCopyA -#define StringCchCopyEx StringCchCopyExA -#define StringCchCopyN StringCchCopyNA -#define StringCchCopyNEx StringCchCopyNExA -#define StringCchGets StringCchGetsA -#define StringCchGetsEx StringCchGetsExA -#define StringCchLength StringCchLengthA -#define StringCchPrintf StringCchPrintfA -#define StringCchPrintfEx StringCchPrintfExA -#define StringCchVPrintf StringCchVPrintfA -#define StringCchVPrintfEx StringCchVPrintfExA -#define _vsnprintfAW _vsnprintf - -#endif // (STRSAFE_UNICODE != 1) -#endif // defined(STRSAFE_UNICODE) - -/*****************************************************************************/ - -#if defined (STRSAFE_PASS2) - -#if defined(STRSAFE_CB) - -#define STRSAFE_CXXtoCB(x) (x) -#define STRSAFE_CBtoCXX(x) (x) -#define STRSAFE_CXXtoCCH(x) (x)/sizeof(STRSAFE_TCHAR) -#define STRSAFE_CCHtoCXX(x) (x)*sizeof(STRSAFE_TCHAR) -#define StringCxxCat StringCbCat -#define StringCxxCatEx StringCbCatEx -#define StringCxxCatN StringCbCatN -#define StringCxxCatNEx StringCbCatNEx -#define StringCxxCatWorker StringCbCatWorker -#define StringCxxCopy StringCbCopy -#define StringCxxCopyEx StringCbCopyEx -#define StringCxxCopyN StringCbCopyN -#define StringCxxCopyNEx StringCbCopyNEx -#define StringCxxGets StringCbGets -#define StringCxxGetsEx StringCbGetsEx -#define StringCxxLength StringCbLength -#define StringCxxPrintf StringCbPrintf -#define StringCxxPrintfEx StringCbPrintfEx -#define StringCxxVPrintf StringCbVPrintf -#define StringCxxVPrintfEx StringCbVPrintfEx - -#else // !STRSAFE_CB - -#define STRSAFE_CXXtoCB(x) (x)*sizeof(STRSAFE_TCHAR) -#define STRSAFE_CBtoCXX(x) (x)/sizeof(STRSAFE_TCHAR) -#define STRSAFE_CXXtoCCH(x) (x) -#define STRSAFE_CCHtoCXX(x) (x) -#define StringCxxCat StringCchCat -#define StringCxxCatEx StringCchCatEx -#define StringCxxCatN StringCchCatN -#define StringCxxCatNEx StringCchCatNEx -#define StringCxxCatWorker StringCchCatWorker -#define StringCxxCopy StringCchCopy -#define StringCxxCopyEx StringCchCopyEx -#define StringCxxCopyN StringCchCopyN -#define StringCxxCopyNEx StringCchCopyNEx -#define StringCxxGets StringCchGets -#define StringCxxGetsEx StringCchGetsEx -#define StringCxxLength StringCchLength -#define StringCxxPrintf StringCchPrintf -#define StringCxxPrintfEx StringCchPrintfEx -#define StringCxxVPrintf StringCchVPrintf -#define StringCxxVPrintfEx StringCchVPrintfEx - -#endif // !STRSAFE_CB - -#ifdef STRSAFE_LIB - -/* Normal function prototypes only */ -#define STRSAFEAPI HRESULT __stdcall - -STRSAFEAPI StringCxxCat(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc); -STRSAFEAPI StringCxxCatEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxCatN(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbMaxAppend); -STRSAFEAPI StringCxxCatNEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbMaxAppend, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxCopy(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc); -STRSAFEAPI StringCxxCopyEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxCopyN(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbSrc); -STRSAFEAPI StringCxxCopyNEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxGets(STRSAFE_LPTSTR pszDest, size_t cxDest); -STRSAFEAPI StringCxxGetsEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxLength(STRSAFE_LPCTSTR psz, size_t cxMax, size_t *pcb); -STRSAFEAPI StringCxxPrintf(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszFormat, ...); -STRSAFEAPI StringCxxPrintfEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCTSTR pszFormat, ...); -STRSAFEAPI StringCxxVPrintf(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszFormat, va_list args); -STRSAFEAPI StringCxxVPrintfEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags, LPCTSTR pszFormat, va_list args); - -#else // !STRSAFE_LIB - -/* Create inlined versions */ -#ifdef __GNUC__ -#define STRSAFEAPI HRESULT static __inline__ -#else -#define STRSAFEAPI HRESULT __inline +#ifndef SUCCEEDED +#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) #endif -#define STRSAFE_MAX_CXX STRSAFE_CCHtoCXX(STRSAFE_MAX_CCH) - -STRSAFEAPI -StringCxxCatWorker( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc, - size_t cxMaxAppend, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags, - int UseN) -{ - HRESULT result; - STRSAFE_LPTSTR psz = pszDest; - size_t cch = STRSAFE_CXXtoCCH(cxDest); - - if (!pszDest || !pszSrc || cxDest > STRSAFE_MAX_CXX || cxDest == 0) - { - return STRSAFE_E_INVALID_PARAMETER; - } - - for (--psz; *(++psz) != 0 && --cch > 0;); - if (cch == 0) - { - return STRSAFE_E_INSUFFICIENT_BUFFER; - } - - if (UseN) - { - cch = STRSAFE_MIN(cxDest, STRSAFE_CXXtoCCH(cxMaxAppend)); - } - - for (--pszSrc, --psz; (*(++psz) = *(++pszSrc)) != 0 && --cch > 0;); - if (cch == 0) - { - result = STRSAFE_E_INSUFFICIENT_BUFFER; - } - else - result = S_OK; - - if (ppszDestEnd) - { - *ppszDestEnd = psz; - } - - if (pcbRemaining) - { - *pcbRemaining = STRSAFE_CCHtoCXX(cch); - } - - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - for (--psz, ++cch; --cch; *(++psz) = dwFlags & 0xff); - } - - if (!SUCCEEDED(result)) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - cch = STRSAFE_CXXtoCCH(cxDest); - for (--pszDest, ++cch; --cch; *(++pszDest) = dwFlags & 0xff); - } - - if (dwFlags & STRSAFE_NULL_ON_FAILURE) - { - *pszDest = 0; - } - } - - return result; -} - -STRSAFEAPI -StringCxxCatEx( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return StringCxxCatWorker(pszDest, cxDest, pszSrc, 0, ppszDestEnd, pcbRemaining, dwFlags, 0); -} - -STRSAFEAPI -StringCxxCat( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc) -{ - return StringCxxCatWorker(pszDest, cxDest, pszSrc, 0, NULL, NULL, 0, 0); -} - -STRSAFEAPI -StringCxxCatN( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc, - size_t cbMaxAppend) -{ - return StringCxxCatWorker(pszDest, cxDest, pszSrc, cbMaxAppend, NULL, NULL, 0, 1); -} - -STRSAFEAPI -StringCxxCatNEx( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc, - size_t cbMaxAppend, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return StringCxxCatWorker(pszDest, cxDest, pszSrc, cbMaxAppend, ppszDestEnd, pcbRemaining, dwFlags, 1); -} - -STRSAFEAPI -StringCxxCopy( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPCTSTR pszSrc) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxCopyEx( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPCTSTR pszSrc, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxCopyN( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPCTSTR pszSrc, - size_t cbSrc) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxCopyNEx( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPCTSTR pszSrc, - size_t cbSrc, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxGets( - STRSAFE_LPTSTR pszDest, - size_t cbDest) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxGetsEx( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxLength( - STRSAFE_LPCTSTR psz, - size_t cxMax, - size_t *pcx) -{ - size_t cch = STRSAFE_CXXtoCCH(cxMax); - - /* Default return on error */ - if (pcx) - *pcx = 0; - - if (!psz || cxMax > STRSAFE_MAX_CXX || cxMax == 0) - { - return STRSAFE_E_INVALID_PARAMETER; - } - - for (--psz; *(++psz) != 0 && --cch > 0;); - - if (cch == 0) - { - return STRSAFE_E_INVALID_PARAMETER; - } - - if (pcx) - *pcx = cxMax - STRSAFE_CCHtoCXX(cch); - - return S_OK; -} - -STRSAFEAPI -StringCxxVPrintfEx( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcxRemaining, - STRSAFE_DWORD dwFlags, - STRSAFE_LPCTSTR pszFormat, - va_list args) -{ - size_t cchDest = STRSAFE_CXXtoCCH(cxDest); - size_t cchMax = cchDest - 1; - int iResult; - HRESULT hr; - - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (!pszDest) pszDest = (STRSAFE_LPTSTR)L""; - if (!pszFormat) pszFormat = (STRSAFE_LPTSTR)L""; - } - - if (!pszDest || !pszFormat || cxDest > STRSAFE_MAX_CXX || cxDest == 0) - { - return STRSAFE_E_INVALID_PARAMETER; - } - -#if (STRSAFE_USE_SECURE_CRT == 1) - iResult = _vsnprintf_sAW(pszDest, cchDest, cchMax, pszFormat, args); -#else - iResult = _vsnprintfAW(pszDest, cchMax, pszFormat, args); +#ifndef FAILED +#define FAILED(hr) ((HRESULT)(hr) < 0) #endif - hr = (iResult == -1) ? STRSAFE_E_INSUFFICIENT_BUFFER : S_OK; +#ifndef S_OK +#define S_OK ((HRESULT)0x00000000L) +#endif - if ((size_t)iResult >= cchMax) - { - pszDest[cchMax] = 0; - iResult = cchMax; +#ifndef C_ASSERT +#ifdef _MSC_VER +# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] +#else +# define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) +#endif +#endif /* C_ASSERT */ + +#ifdef __cplusplus +#define _STRSAFE_EXTERN_C extern "C" +#else +#define _STRSAFE_EXTERN_C extern +#endif + +#ifndef WINAPI +#define WINAPI __stdcall +#endif + +#define STRSAFEAPI static __inline HRESULT WINAPI +#define STRSAFE_INLINE_API __CRT_INLINE HRESULT WINAPI + +#define STRSAFE_MAX_CCH 2147483647 + +#ifndef _NTSTRSAFE_H_INCLUDED_ +#define STRSAFE_IGNORE_NULLS 0x00000100 +#define STRSAFE_FILL_BEHIND_NULL 0x00000200 +#define STRSAFE_FILL_ON_FAILURE 0x00000400 +#define STRSAFE_NULL_ON_FAILURE 0x00000800 +#define STRSAFE_NO_TRUNCATION 0x00001000 +#define STRSAFE_IGNORE_NULL_UNICODE_STRINGS 0x00010000 +#define STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED 0x00020000 + +#define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION) +#define STRSAFE_UNICODE_STRING_VALID_FLAGS (STRSAFE_VALID_FLAGS | STRSAFE_IGNORE_NULL_UNICODE_STRINGS | STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED) + +#define STRSAFE_FILL_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL)) +#define STRSAFE_FAILURE_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_ON_FAILURE)) + +#define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)((dwFlags) & 0x000000FF)) +#endif + +#define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) +#define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L) +#define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L) + +typedef char *STRSAFE_LPSTR; +typedef const char *STRSAFE_LPCSTR; +typedef wchar_t *STRSAFE_LPWSTR; +typedef const wchar_t *STRSAFE_LPCWSTR; + +typedef ULONG STRSAFE_DWORD; + +STRSAFEAPI StringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); +STRSAFEAPI StringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy); +STRSAFEAPI StringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy); +STRSAFEAPI StringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); +STRSAFEAPI StringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend); +STRSAFEAPI StringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend); +STRSAFEAPI StringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList); +STRSAFEAPI StringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); +STRSAFEAPI StringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength); +STRSAFEAPI StringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength); +STRSAFE_INLINE_API StringGetsExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFE_INLINE_API StringGetsExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchCopy __MINGW_NAME_AW(StringCchCopy) + +STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { + return (cchDest > STRSAFE_MAX_CCH ? STRSAFE_E_INVALID_PARAMETER : StringCopyWorkerA(pszDest,cchDest,pszSrc)); +} + +STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyWorkerW(pszDest,cchDest,pszSrc); +} +#endif /* !__CRT__NO_INLINE */ + +#define StringCbCopy __MINGW_NAME_AW(StringCbCopy) + +STRSAFEAPI StringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc); + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc) { + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyWorkerA(pszDest,cbDest,pszSrc); +} + +STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc) { + size_t cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyWorkerW(pszDest,cchDest,pszSrc); +} +#endif /* !__CRT__NO_INLINE */ + +#define StringCchCopyEx __MINGW_NAME_AW(StringCchCopyEx) + +STRSAFEAPI StringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + +STRSAFEAPI StringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + size_t cbDest; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + cbDest = cchDest * sizeof(wchar_t); + return StringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} +#endif /* !__CRT__NO_INLINE */ + +#define StringCbCopyEx __MINGW_NAME_AW(StringCbCopyEx) + +STRSAFEAPI StringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchRemaining = 0; + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + hr = StringCopyExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if(SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) { + if(pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + } + return hr; +} + +STRSAFEAPI StringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchRemaining = 0; + + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + hr = StringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy); +STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy); +#define StringCchCopyN __MINGW_NAME_AW(StringCchCopyN) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy) { + if(cchDest > STRSAFE_MAX_CCH || cchToCopy > STRSAFE_MAX_CCH) + return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNWorkerA(pszDest,cchDest,pszSrc,cchToCopy); +} + +STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy) { + if(cchDest > STRSAFE_MAX_CCH || cchToCopy > STRSAFE_MAX_CCH) + return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy); +STRSAFEAPI StringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy); + +#define StringCbCopyN __MINGW_NAME_AW(StringCbCopyN) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy) { + if(cbDest > STRSAFE_MAX_CCH || cbToCopy > STRSAFE_MAX_CCH) + return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNWorkerA(pszDest,cbDest,pszSrc,cbToCopy); +} + +STRSAFEAPI StringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy) { + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH || cchToCopy > STRSAFE_MAX_CCH) + return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchCopyNEx __MINGW_NAME_AW(StringCchCopyNEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags); +} + +STRSAFEAPI StringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNExWorkerW(pszDest,cchDest,cchDest * sizeof(wchar_t),pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + +#define StringCbCopyNEx __MINGW_NAME_AW(StringCbCopyNEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchRemaining = 0; + if(cbDest > STRSAFE_MAX_CCH) + hr = STRSAFE_E_INVALID_PARAMETER; + else + hr = StringCopyNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToCopy,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = cchRemaining; + return hr; +} + +STRSAFEAPI StringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest; + size_t cchToCopy; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + cchToCopy = cbToCopy / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCopyNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToCopy,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); + +#define StringCchCat __MINGW_NAME_AW(StringCchCat) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatWorkerA(pszDest,cchDest,pszSrc); +} + +STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatWorkerW(pszDest,cchDest,pszSrc); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc); + +#define StringCbCat __MINGW_NAME_AW(StringCbCat) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc) { + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatWorkerA(pszDest,cbDest,pszSrc); +} + +STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc) { + size_t cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatWorkerW(pszDest,cchDest,pszSrc); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchCatEx __MINGW_NAME_AW(StringCchCatEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + +STRSAFEAPI StringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + size_t cbDest = cchDest*sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + +#define StringCbCatEx __MINGW_NAME_AW(StringCbCatEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchRemaining = 0; + if(cbDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCatExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + return hr; +} + +STRSAFEAPI StringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchRemaining = 0; + + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend); +STRSAFEAPI StringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend); + +#define StringCchCatN __MINGW_NAME_AW(StringCchCatN) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNWorkerA(pszDest,cchDest,pszSrc,cchToAppend); +} + +STRSAFEAPI StringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend); +STRSAFEAPI StringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend); + +#define StringCbCatN __MINGW_NAME_AW(StringCbCatN) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend) { + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNWorkerA(pszDest,cbDest,pszSrc,cbToAppend); +} + +STRSAFEAPI StringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend) { + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchCatNEx __MINGW_NAME_AW(StringCchCatNEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags); +} + +STRSAFEAPI StringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNExWorkerW(pszDest,cchDest,(cchDest*sizeof(wchar_t)),pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags); +} +#endif + +STRSAFEAPI StringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + +#define StringCbCatNEx __MINGW_NAME_AW(StringCbCatNEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchRemaining = 0; + if(cbDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCatNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToAppend,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + return hr; +} + +STRSAFEAPI StringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + size_t cchRemaining = 0; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCatNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToAppend,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList); + +#define StringCchVPrintf __MINGW_NAME_AW(StringCchVPrintf) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList); +} + +STRSAFEAPI StringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList); + +#define StringCbVPrintf __MINGW_NAME_AW(StringCbVPrintf) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList) { + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList); +} + +STRSAFEAPI StringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList) { + size_t cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...); +STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...); + +#define StringCchPrintf __MINGW_NAME_AW(StringCchPrintf) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...) { + HRESULT hr; + va_list argList; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return hr; +} + +STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...) { + HRESULT hr; + va_list argList; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...); +STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...); + +#define StringCbPrintf __MINGW_NAME_AW(StringCbPrintf) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...) { + HRESULT hr; + va_list argList; + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList); + va_end(argList); + return hr; +} + +STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...) { + HRESULT hr; + va_list argList; + size_t cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...); +STRSAFEAPI StringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...); + +#define StringCchPrintfEx __MINGW_NAME_AW(StringCchPrintfEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...) { + HRESULT hr; + va_list argList; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfExWorkerA(pszDest,cchDest,cchDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + return hr; +} + +STRSAFEAPI StringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...) { + HRESULT hr; + size_t cbDest = cchDest * sizeof(wchar_t); + va_list argList; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...); +STRSAFEAPI StringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...); + +#define StringCbPrintfEx __MINGW_NAME_AW(StringCbPrintfEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + va_list argList; + va_start(argList,pszFormat); + hr = StringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) { + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); } + } + return hr; +} - if (ppszDestEnd) *ppszDestEnd = pszDest + iResult; - - if (pcxRemaining) *pcxRemaining = STRSAFE_CCHtoCXX(cchMax - iResult); - - if (SUCCEEDED(hr)) - { - if ((dwFlags & STRSAFE_FILL_BEHIND_NULL) && ((size_t)iResult + 1 < cchMax)) - { - memset(pszDest + iResult + 1, - dwFlags & 0xff, - (cchMax - iResult - 1) * sizeof(STRSAFE_TCHAR)); - } +STRSAFEAPI StringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + va_list argList; + va_start(argList,pszFormat); + hr = StringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) { + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); } - else - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, dwFlags & 0xff, cchMax * sizeof(STRSAFE_TCHAR)); - } - else if (dwFlags & STRSAFE_NULL_ON_FAILURE) - { - *pszDest = 0; - } + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); + +#define StringCchVPrintfEx __MINGW_NAME_AW(StringCchVPrintfEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(char); + hr = StringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + } + return hr; +} + +STRSAFEAPI StringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(wchar_t); + hr = StringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); + +#define StringCbVPrintfEx __MINGW_NAME_AW(StringCbVPrintfEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) { + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); } - - return hr; + } + return hr; } -STRSAFEAPI -StringCxxVPrintf( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszFormat, - va_list args) -{ - return StringCxxVPrintfEx(pszDest, cxDest, NULL, NULL, 0, pszFormat, args); +STRSAFEAPI StringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) { + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFE_INLINE_API StringCchGetsA(STRSAFE_LPSTR pszDest,size_t cchDest); +STRSAFE_INLINE_API StringCchGetsW(STRSAFE_LPWSTR pszDest,size_t cchDest); + +#define StringCchGets __MINGW_NAME_AW(StringCchGets) + +#ifndef __CRT__NO_INLINE +STRSAFE_INLINE_API StringCchGetsA(STRSAFE_LPSTR pszDest,size_t cchDest) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(char); + hr = StringGetsExWorkerA(pszDest,cchDest,cbDest,NULL,NULL,0); + } + return hr; } -STRSAFEAPI -StringCxxPrintf( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszFormat, ...) -{ - HRESULT result; - va_list args; - va_start(args, pszFormat); - result = StringCxxVPrintf(pszDest, cxDest, pszFormat, args); - va_end(args); - return result; +STRSAFE_INLINE_API StringCchGetsW(STRSAFE_LPWSTR pszDest,size_t cchDest) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(wchar_t); + hr = StringGetsExWorkerW(pszDest,cchDest,cbDest,NULL,NULL,0); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFE_INLINE_API StringCbGetsA(STRSAFE_LPSTR pszDest,size_t cbDest); +STRSAFE_INLINE_API StringCbGetsW(STRSAFE_LPWSTR pszDest,size_t cbDest); + +#define StringCbGets __MINGW_NAME_AW(StringCbGets) + +#ifndef __CRT__NO_INLINE +STRSAFE_INLINE_API StringCbGetsA(STRSAFE_LPSTR pszDest,size_t cbDest) { + HRESULT hr; + size_t cchDest; + cchDest = cbDest / sizeof(char); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringGetsExWorkerA(pszDest,cchDest,cbDest,NULL,NULL,0); + return hr; } -STRSAFEAPI -StringCxxPrintfEx( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags, - STRSAFE_LPCTSTR pszFormat, ...) -{ - HRESULT result; - va_list args; - va_start(args, pszFormat); - result = StringCxxVPrintfEx(pszDest, cxDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, args); - va_end(args); - return result; +STRSAFE_INLINE_API StringCbGetsW(STRSAFE_LPWSTR pszDest,size_t cbDest) { + HRESULT hr; + size_t cchDest; + cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringGetsExWorkerW(pszDest,cchDest,cbDest,NULL,NULL,0); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFE_INLINE_API StringCchGetsExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFE_INLINE_API StringCchGetsExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchGetsEx __MINGW_NAME_AW(StringCchGetsEx) + +#ifndef __CRT__NO_INLINE +STRSAFE_INLINE_API StringCchGetsExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(char); + hr = StringGetsExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags); + } + return hr; } -#endif // !STRSAFE_LIB +STRSAFE_INLINE_API StringCchGetsExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(wchar_t); + hr = StringGetsExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ -/* Functions are implemented or defined, clear #defines for next pass */ -#undef StringCxxCat -#undef StringCxxCatEx -#undef StringCxxCatN -#undef StringCxxCatNEx -#undef StringCxxCatWorker -#undef StringCxxCopy -#undef StringCxxCopyEx -#undef StringCxxCopyN -#undef StringCxxCopyNEx -#undef StringCxxGets -#undef StringCxxGetsEx -#undef StringCxxLength -#undef StringCxxPrintf -#undef StringCxxPrintfEx -#undef StringCxxVPrintf -#undef StringCxxVPrintfEx +STRSAFE_INLINE_API StringCbGetsExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFE_INLINE_API StringCbGetsExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); -#undef StringCbCat -#undef StringCbCatEx -#undef StringCbCatN -#undef StringCbCatNEx -#undef StringCbCatWorker -#undef StringCbCopy -#undef StringCbCopyEx -#undef StringCbCopyN -#undef StringCbCopyNEx -#undef StringCbGets -#undef StringCbGetsEx -#undef StringCbLength -#undef StringCbPrintf -#undef StringCbPrintfEx -#undef StringCbVPrintf -#undef StringCbVPrintfEx -#undef StringCchCat -#undef StringCchCatEx -#undef StringCchCatN -#undef StringCchCatNEx -#undef StringCchCatWorker -#undef StringCchCopy -#undef StringCchCopyEx -#undef StringCchCopyN -#undef StringCchCopyNEx -#undef StringCchGets -#undef StringCchGetsEx -#undef StringCchLength -#undef StringCchPrintf -#undef StringCchPrintfEx -#undef StringCchVPrintf -#undef StringCchVPrintfEx -#undef _vsnprintfAW +#define StringCbGetsEx __MINGW_NAME_AW(StringCbGetsEx) -#undef STRSAFE_LPTSTR -#undef STRSAFE_LPCTSTR -#undef STRSAFE_TCHAR +#ifndef __CRT__NO_INLINE +STRSAFE_INLINE_API StringCbGetsExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringGetsExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER) || (hr==STRSAFE_E_END_OF_FILE)) { + if(pcbRemaining) *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + } + return hr; +} -#undef STRSAFE_CXXtoCB -#undef STRSAFE_CBtoCXX -#undef STRSAFE_CXXtoCCH -#undef STRSAFE_CCHtoCXX +STRSAFE_INLINE_API StringCbGetsExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringGetsExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER) || (hr==STRSAFE_E_END_OF_FILE)) { + if(pcbRemaining) *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ -#endif // defined (STRSAFE_PASS2) +STRSAFEAPI StringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength); +STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength); +#define StringCchLength __MINGW_NAME_AW(StringCchLength) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength) { + HRESULT hr; + if(!psz || (cchMax > STRSAFE_MAX_CCH)) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringLengthWorkerA(psz,cchMax,pcchLength); + if(FAILED(hr) && pcchLength) { + *pcchLength = 0; + } + return hr; +} + +STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength) { + HRESULT hr; + if(!psz || (cchMax > STRSAFE_MAX_CCH)) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringLengthWorkerW(psz,cchMax,pcchLength); + if(FAILED(hr) && pcchLength) { + *pcchLength = 0; + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength); +STRSAFEAPI StringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength); + +#define StringCbLength __MINGW_NAME_AW(StringCbLength) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength) { + HRESULT hr; + size_t cchMax; + size_t cchLength = 0; + cchMax = cbMax / sizeof(char); + if(!psz || (cchMax > STRSAFE_MAX_CCH)) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringLengthWorkerA(psz,cchMax,&cchLength); + if(pcbLength) { + if(SUCCEEDED(hr)) { + *pcbLength = cchLength*sizeof(char); + } else { + *pcbLength = 0; + } + } + return hr; +} + +STRSAFEAPI StringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength) { + HRESULT hr; + size_t cchMax; + size_t cchLength = 0; + cchMax = cbMax / sizeof(wchar_t); + if(!psz || (cchMax > STRSAFE_MAX_CCH)) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringLengthWorkerW(psz,cchMax,&cchLength); + if(pcbLength) { + if(SUCCEEDED(hr)) { + *pcbLength = cchLength*sizeof(wchar_t); + } else { + *pcbLength = 0; + } + } + return hr; +} + +STRSAFEAPI StringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + while(cchDest && (*pszSrc!='\0')) { + *pszDest++ = *pszSrc++; + cchDest--; + } + if(cchDest==0) { + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDest= '\0'; + } + return hr; +} + +STRSAFEAPI StringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + while(cchDest && (*pszSrc!=L'\0')) { + *pszDest++ = *pszSrc++; + cchDest--; + } + if(cchDest==0) { + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDest= L'\0'; + } + return hr; +} + +STRSAFEAPI StringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszSrc) pszSrc = ""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if(*pszSrc!='\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && (*pszSrc!='\0')) { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } else { + pszDestEnd--; + cchRemaining++; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDestEnd = '\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszSrc) pszSrc = L""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if(*pszSrc!=L'\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && (*pszSrc!=L'\0')) { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } else { + pszDestEnd--; + cchRemaining++; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDestEnd = L'\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchSrc) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + while(cchDest && cchSrc && (*pszSrc!='\0')) { + *pszDest++ = *pszSrc++; + cchDest--; + cchSrc--; + } + if(cchDest==0) { + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDest= '\0'; + } + return hr; +} + +STRSAFEAPI StringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + while(cchDest && cchToCopy && (*pszSrc!=L'\0')) { + *pszDest++ = *pszSrc++; + cchDest--; + cchToCopy--; + } + if(cchDest==0) { + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDest= L'\0'; + } + return hr; +} + +STRSAFEAPI StringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else if(cchToCopy > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszSrc) pszSrc = ""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if((cchToCopy!=0) && (*pszSrc!='\0')) { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && cchToCopy && (*pszSrc!='\0')) { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + cchToCopy--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } else { + pszDestEnd--; + cchRemaining++; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDestEnd = '\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else if(cchToCopy > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszSrc) pszSrc = L""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if((cchToCopy!=0) && (*pszSrc!=L'\0')) { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && cchToCopy && (*pszSrc!=L'\0')) { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + cchToCopy--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } else { + pszDestEnd--; + cchRemaining++; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDestEnd = L'\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { + HRESULT hr; + size_t cchDestLength; + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) hr = StringCopyWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc); + return hr; +} + +STRSAFEAPI StringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { + HRESULT hr; + size_t cchDestLength; + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) hr = StringCopyWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc); + return hr; +} + +STRSAFEAPI StringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cchDestLength; + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest==0) && (cbDest==0)) cchDestLength = 0; + else hr = STRSAFE_E_INVALID_PARAMETER; + } else { + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(!pszSrc) pszSrc = ""; + } else { + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + if(*pszSrc!='\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else hr = StringCopyExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & STRSAFE_NULL_ON_FAILURE) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cchDestLength; + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest==0) && (cbDest==0)) cchDestLength = 0; + else hr = STRSAFE_E_INVALID_PARAMETER; + } else { + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(!pszSrc) pszSrc = L""; + } else { + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + if(*pszSrc!=L'\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else hr = StringCopyExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & STRSAFE_NULL_ON_FAILURE) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend) { + HRESULT hr; + size_t cchDestLength; + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) hr = StringCopyNWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend); + return hr; +} + +STRSAFEAPI StringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend) { + HRESULT hr; + size_t cchDestLength; + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) hr = StringCopyNWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend); + return hr; +} + +STRSAFEAPI StringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestLength = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else if(cchToAppend > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest==0) && (cbDest==0)) cchDestLength = 0; + else hr = STRSAFE_E_INVALID_PARAMETER; + } else { + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(!pszSrc) pszSrc = ""; + } else { + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + if((cchToAppend!=0) && (*pszSrc!='\0')) { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else hr = StringCopyNExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestLength = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else if(cchToAppend > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest==0) && (cbDest==0)) cchDestLength = 0; + else hr = STRSAFE_E_INVALID_PARAMETER; + } else { + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(!pszSrc) pszSrc = L""; + } else { + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + if((cchToAppend!=0) && (*pszSrc!=L'\0')) { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else hr = StringCopyNExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList); + if((iRet < 0) || (((size_t)iRet) > cchMax)) { + pszDest += cchMax; + *pszDest = '\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else if(((size_t)iRet)==cchMax) { + pszDest += cchMax; + *pszDest = '\0'; + } + } + return hr; +} + +STRSAFEAPI StringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList); + if((iRet < 0) || (((size_t)iRet) > cchMax)) { + pszDest += cchMax; + *pszDest = L'\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else if(((size_t)iRet)==cchMax) { + pszDest += cchMax; + *pszDest = L'\0'; + } + } + return hr; +} + +STRSAFEAPI StringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszFormat) pszFormat = ""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if(*pszFormat!='\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList); + if((iRet < 0) || (((size_t)iRet) > cchMax)) { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = '\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else if(((size_t)iRet)==cchMax) { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = '\0'; + } else if(((size_t)iRet) < cchMax) { + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszFormat) pszFormat = L""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if(*pszFormat!=L'\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList); + if((iRet < 0) || (((size_t)iRet) > cchMax)) { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = L'\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else if(((size_t)iRet)==cchMax) { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } else if(((size_t)iRet) < cchMax) { + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength) { + HRESULT hr = S_OK; + size_t cchMaxPrev = cchMax; + while(cchMax && (*psz!='\0')) { + psz++; + cchMax--; + } + if(cchMax==0) hr = STRSAFE_E_INVALID_PARAMETER; + if(pcchLength) { + if(SUCCEEDED(hr)) *pcchLength = cchMaxPrev - cchMax; + else *pcchLength = 0; + } + return hr; +} + +STRSAFEAPI StringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength) { + HRESULT hr = S_OK; + size_t cchMaxPrev = cchMax; + while(cchMax && (*psz!=L'\0')) { + psz++; + cchMax--; + } + if(cchMax==0) hr = STRSAFE_E_INVALID_PARAMETER; + if(pcchLength) { + if(SUCCEEDED(hr)) *pcchLength = cchMaxPrev - cchMax; + else *pcchLength = 0; + } + return hr; +} + +STRSAFE_INLINE_API StringGetsExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + } + if(SUCCEEDED(hr)) { + if(cchDest <= 1) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + if(cchDest==1) *pszDestEnd = '\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining > 1) { + char ch; + int i = getc(stdin); + if(i==EOF) { + if(pszDestEnd==pszDest) hr = STRSAFE_E_END_OF_FILE; + break; + } + ch = (char)i; + if(ch=='\n') break; + *pszDestEnd = ch; + pszDestEnd++; + cchRemaining--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + *pszDestEnd = '\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER) || (hr==STRSAFE_E_END_OF_FILE)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFE_INLINE_API StringGetsExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) { + hr = STRSAFE_E_INVALID_PARAMETER; + } else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + } + if(SUCCEEDED(hr)) { + if(cchDest <= 1) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + if(cchDest==1) *pszDestEnd = L'\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining > 1) { + wchar_t ch = getwc(stdin); + if(ch==WEOF) { + if(pszDestEnd==pszDest) hr = STRSAFE_E_END_OF_FILE; + break; + } + if(ch==L'\n') break; + *pszDestEnd = ch; + pszDestEnd++; + cchRemaining--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + *pszDestEnd = L'\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER) || (hr==STRSAFE_E_END_OF_FILE)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +#define StringCopyWorkerA StringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define StringCopyWorkerW StringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define StringCopyExWorkerA StringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define StringCopyExWorkerW StringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define StringCatWorkerA StringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define StringCatWorkerW StringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define StringCatExWorkerA StringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define StringCatExWorkerW StringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define StringCatNWorkerA StringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA; +#define StringCatNWorkerW StringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW; +#define StringCatNExWorkerA StringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA; +#define StringCatNExWorkerW StringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW; +#define StringVPrintfWorkerA StringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define StringVPrintfWorkerW StringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define StringVPrintfExWorkerA StringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define StringVPrintfExWorkerW StringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define StringLengthWorkerA StringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA; +#define StringLengthWorkerW StringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW; +#define StringGetsExWorkerA StringGetsExWorkerA_instead_use_StringCchGetsA_or_StringCbGetsA +#define StringGetsExWorkerW StringGetsExWorkerW_instead_use_StringCchGetsW_or_StringCbGetsW + +/* Some Wine modules include us, don't specify STRSAFE_NO_DEPRECATE, and use deprecated functions */ +#ifndef STRSAFE_NO_DEPRECATE +#define STRSAFE_NO_DEPRECATE +#endif + +#ifndef STRSAFE_NO_DEPRECATE + +#undef strcpy +#define strcpy strcpy_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef wcscpy +#define wcscpy wcscpy_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef strcat +#define strcat strcat_instead_use_StringCbCatA_or_StringCchCatA; + +#undef wcscat +#define wcscat wcscat_instead_use_StringCbCatW_or_StringCchCatW; + +#undef sprintf +#define sprintf sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef swprintf +#define swprintf swprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef vsprintf +#define vsprintf vsprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef vswprintf +#define vswprintf vswprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef _snprintf +#define _snprintf _snprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef _snwprintf +#define _snwprintf _snwprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef _vsnprintf +#define _vsnprintf _vsnprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef _vsnwprintf +#define _vsnwprintf _vsnwprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef strcpyA +#define strcpyA strcpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef strcpyW +#define strcpyW strcpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef lstrcpy +#define lstrcpy lstrcpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef lstrcpyA +#define lstrcpyA lstrcpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef lstrcpyW +#define lstrcpyW lstrcpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef StrCpy +#define StrCpy StrCpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef StrCpyA +#define StrCpyA StrCpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef StrCpyW +#define StrCpyW StrCpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef _tcscpy +#define _tcscpy _tcscpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef _ftcscpy +#define _ftcscpy _ftcscpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef lstrcat +#define lstrcat lstrcat_instead_use_StringCbCat_or_StringCchCat; + +#undef lstrcatA +#define lstrcatA lstrcatA_instead_use_StringCbCatA_or_StringCchCatA; + +#undef lstrcatW +#define lstrcatW lstrcatW_instead_use_StringCbCatW_or_StringCchCatW; + +#undef StrCat +#define StrCat StrCat_instead_use_StringCbCat_or_StringCchCat; + +#undef StrCatA +#define StrCatA StrCatA_instead_use_StringCbCatA_or_StringCchCatA; + +#undef StrCatW +#define StrCatW StrCatW_instead_use_StringCbCatW_or_StringCchCatW; + +#undef StrNCat +#define StrNCat StrNCat_instead_use_StringCbCatN_or_StringCchCatN; + +#undef StrNCatA +#define StrNCatA StrNCatA_instead_use_StringCbCatNA_or_StringCchCatNA; + +#undef StrNCatW +#define StrNCatW StrNCatW_instead_use_StringCbCatNW_or_StringCchCatNW; + +#undef StrCatN +#define StrCatN StrCatN_instead_use_StringCbCatN_or_StringCchCatN; + +#undef StrCatNA +#define StrCatNA StrCatNA_instead_use_StringCbCatNA_or_StringCchCatNA; + +#undef StrCatNW +#define StrCatNW StrCatNW_instead_use_StringCbCatNW_or_StringCchCatNW; + +#undef _tcscat +#define _tcscat _tcscat_instead_use_StringCbCat_or_StringCchCat; + +#undef _ftcscat +#define _ftcscat _ftcscat_instead_use_StringCbCat_or_StringCchCat; + +#undef wsprintf +#define wsprintf wsprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef wsprintfA +#define wsprintfA wsprintfA_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef wsprintfW +#define wsprintfW wsprintfW_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef wvsprintf +#define wvsprintf wvsprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef wvsprintfA +#define wvsprintfA wvsprintfA_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef wvsprintfW +#define wvsprintfW wvsprintfW_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef _vstprintf +#define _vstprintf _vstprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef _vsntprintf +#define _vsntprintf _vsntprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef _stprintf +#define _stprintf _stprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef _sntprintf +#define _sntprintf _sntprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef _getts +#define _getts _getts_instead_use_StringCbGets_or_StringCchGets; + +#undef gets +#define gets _gets_instead_use_StringCbGetsA_or_StringCchGetsA; + +#undef _getws +#define _getws _getws_instead_use_StringCbGetsW_or_StringCchGetsW; +#endif +#endif diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 3e2066dc482..f614cf659e2 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -12,7 +12,6 @@ #include #define NDEBUG #include -#include "ntstrsafe.h" /* Temporary hack */ BOOLEAN @@ -44,7 +43,7 @@ ULONG NtBuildNumber = VER_PRODUCTBUILD; #endif /* NT System Info */ -ULONG NtGlobalFlag; +ULONG NtGlobalFlag = 0; ULONG ExSuiteMask; /* Cm Version Info */ @@ -894,7 +893,7 @@ ExpInitializeExecutive(IN ULONG Cpu, PLDR_DATA_TABLE_ENTRY NtosEntry; PMESSAGE_RESOURCE_ENTRY MsgEntry; ANSI_STRING CsdString; - SIZE_T Remaining = 0; + size_t Remaining = 0; PCHAR RcEnd = NULL; CHAR VersionBuffer [65]; @@ -1311,6 +1310,7 @@ Phase1InitializationDiscard(IN PVOID Context) ANSI_STRING TempString; ULONG LastTzBias, Length, YearHack = 0, Disposition, MessageCode = 0; SIZE_T Size; + size_t Remaining; PRTL_USER_PROCESS_INFORMATION ProcessInfo; KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo; UNICODE_STRING KeyName, DebugString; @@ -1390,14 +1390,14 @@ Phase1InitializationDiscard(IN PVOID Context) StringBuffer = InitBuffer->VersionBuffer; BeginBuffer = StringBuffer; EndBuffer = StringBuffer; - Size = 256; + Remaining = sizeof(InitBuffer->VersionBuffer); if (CmCSDVersionString.Length) { /* Print the version string */ Status = RtlStringCbPrintfExA(StringBuffer, - 255, + Remaining, &EndBuffer, - &Size, + &Remaining, 0, ": %wZ", &CmCSDVersionString); @@ -1410,16 +1410,14 @@ Phase1InitializationDiscard(IN PVOID Context) else { /* No version */ - Size = 255; + *EndBuffer++ = ANSI_NULL; /* Null-terminate the string */ + --Remaining; } - /* Null-terminate the string */ - *EndBuffer++ = ANSI_NULL; - /* Build the version number */ StringBuffer = InitBuffer->VersionNumber; Status = RtlStringCbPrintfA(StringBuffer, - 24, + sizeof(InitBuffer->VersionNumber), "%u.%u", VER_PRODUCTMAJORVERSION, VER_PRODUCTMINORVERSION); @@ -1434,7 +1432,7 @@ Phase1InitializationDiscard(IN PVOID Context) { /* Create the banner message */ Status = RtlStringCbPrintfA(EndBuffer, - Size, + Remaining, (PCHAR)MsgEntry->Text, StringBuffer, NtBuildNumber & 0xFFFF, @@ -1448,7 +1446,7 @@ Phase1InitializationDiscard(IN PVOID Context) else { /* Use hard-coded banner message */ - Status = RtlStringCbCopyA(EndBuffer, Size, "REACTOS (R)\n"); + Status = RtlStringCbCopyA(EndBuffer, Remaining, "REACTOS (R)\n"); if (!NT_SUCCESS(Status)) { /* Bugcheck */ @@ -1548,7 +1546,7 @@ Phase1InitializationDiscard(IN PVOID Context) /* Create the string */ StringBuffer = InitBuffer->VersionBuffer; Status = RtlStringCbPrintfA(StringBuffer, - 256, + sizeof(InitBuffer->VersionBuffer), NT_SUCCESS(MsgStatus) ? (PCHAR)MsgEntry->Text : "%u System Processor [%u MB Memory] %Z\n", From c14b8afbdcfa3aead6fbef5f9a2cb39f340d3ab3 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 21:49:03 +0000 Subject: [PATCH 72/90] Forgotten in r51135... svn path=/trunk/; revision=51136 --- reactos/ntoskrnl/include/ntoskrnl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/ntoskrnl/include/ntoskrnl.h b/reactos/ntoskrnl/include/ntoskrnl.h index 4261d020544..40c03b89d1d 100644 --- a/reactos/ntoskrnl/include/ntoskrnl.h +++ b/reactos/ntoskrnl/include/ntoskrnl.h @@ -36,6 +36,7 @@ #undef TEXT #define TEXT(s) L##s #include +#include /* FIXME: Temporary until Winldr is used */ #include From 54dc46543f805518571af77d26f300c450b08b9f Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 21:58:39 +0000 Subject: [PATCH 73/90] [USER32] Fix bug causing no NULL termination of strings after conversion in EnumDisplayDevicesA. Fixes one usr32:monitor winetest svn path=/trunk/; revision=51137 --- reactos/dll/win32/user32/misc/display.c | 30 +++++++++++-------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/reactos/dll/win32/user32/misc/display.c b/reactos/dll/win32/user32/misc/display.c index e9de23e4e4a..f00be9b7ad9 100644 --- a/reactos/dll/win32/user32/misc/display.c +++ b/reactos/dll/win32/user32/misc/display.c @@ -71,24 +71,20 @@ EnumDisplayDevicesA( dwFlags ); if (rc) { - /* Copy result from DisplayDeviceW to lpDisplayDevice */ + /* Copy result from DisplayDeviceW to lpDisplayDevice. Buffers have the same size so result is always NULL terminated. */ lpDisplayDevice->StateFlags = DisplayDeviceW.StateFlags; - WideCharToMultiByte(CP_ACP,0, - DisplayDeviceW.DeviceName,wcslen(DisplayDeviceW.DeviceName), - lpDisplayDevice->DeviceName,sizeof(lpDisplayDevice->DeviceName) / sizeof(lpDisplayDevice->DeviceName[0]), - NULL,NULL); - WideCharToMultiByte(CP_ACP,0, - DisplayDeviceW.DeviceString,wcslen(DisplayDeviceW.DeviceString), - lpDisplayDevice->DeviceString,sizeof(lpDisplayDevice->DeviceString) / sizeof(lpDisplayDevice->DeviceString[0]), - NULL,NULL); - WideCharToMultiByte(CP_ACP,0, - DisplayDeviceW.DeviceID,wcslen(DisplayDeviceW.DeviceID), - lpDisplayDevice->DeviceID,sizeof(lpDisplayDevice->DeviceID) / sizeof(lpDisplayDevice->DeviceID[0]), - NULL,NULL); - WideCharToMultiByte(CP_ACP,0, - DisplayDeviceW.DeviceKey,wcslen(DisplayDeviceW.DeviceKey), - lpDisplayDevice->DeviceKey,sizeof(lpDisplayDevice->DeviceKey) / sizeof(lpDisplayDevice->DeviceKey[0]), - NULL,NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceName, -1, + lpDisplayDevice->DeviceName, sizeof(lpDisplayDevice->DeviceName) / sizeof(lpDisplayDevice->DeviceName[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceString, -1, + lpDisplayDevice->DeviceString, sizeof(lpDisplayDevice->DeviceString) / sizeof(lpDisplayDevice->DeviceString[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceID, -1, + lpDisplayDevice->DeviceID, sizeof(lpDisplayDevice->DeviceID) / sizeof(lpDisplayDevice->DeviceID[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceKey, -1, + lpDisplayDevice->DeviceKey, sizeof(lpDisplayDevice->DeviceKey) / sizeof(lpDisplayDevice->DeviceKey[0]), + NULL, NULL); } RtlFreeUnicodeString ( &Device ); From 547a7d215fa680ba6a8126fce2d59cefaf769263 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 22:28:15 +0000 Subject: [PATCH 74/90] [NTOSKRNL] Change strncpy calls to RtlStringSbCopyA (PART 1/x) Fix bug in MmLoadSystemImage which caused FileName parameter to be freed svn path=/trunk/; revision=51138 --- reactos/ntoskrnl/kdbg/kdb_cli.c | 9 +++------ reactos/ntoskrnl/ke/freeldr.c | 17 ++++++++++------- reactos/ntoskrnl/mm/ARM3/sysldr.c | 10 +++++----- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/reactos/ntoskrnl/kdbg/kdb_cli.c b/reactos/ntoskrnl/kdbg/kdb_cli.c index a0d5135f929..a45009cf7c1 100644 --- a/reactos/ntoskrnl/kdbg/kdb_cli.c +++ b/reactos/ntoskrnl/kdbg/kdb_cli.c @@ -2490,14 +2490,12 @@ KdbpReadCommand( */ if (Buffer == Orig) { - strncpy(Buffer, LastCommand, Size); - Buffer[Size - 1] = '\0'; + RtlStringCbCopyA(Buffer, Size, LastCommand); } else { *Buffer = '\0'; - strncpy(LastCommand, Orig, sizeof (LastCommand)); - LastCommand[sizeof (LastCommand) - 1] = '\0'; + RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Orig); } return; @@ -2614,8 +2612,7 @@ KdbpDoCommand( static PCH Argv[256]; static CHAR OrigCommand[1024]; - strncpy(OrigCommand, Command, sizeof(OrigCommand) - 1); - OrigCommand[sizeof(OrigCommand) - 1] = '\0'; + RtlStringCbCopyA(OrigCommand, sizeof(OrigCommand), Command); Argc = 0; p = Command; diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 9dfc8eb9e07..2e0d17ce178 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -947,6 +947,8 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, WCHAR PathSetup[] = L"\\SystemRoot\\"; CHAR DriverNameLow[256]; ULONG Base; + size_t Remaining; + WCHAR *StringEnd; #if defined(_PPC_) ULONG KernelBase = RosLoaderBlock->ModsAddr[0].ModStart; #endif @@ -1123,7 +1125,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, /* Construct a correct full name */ BldrModuleStringsFull[i][0] = 0; - LdrEntry->FullDllName.MaximumLength = 260 * sizeof(WCHAR); + LdrEntry->FullDllName.MaximumLength = sizeof(BldrModuleStringsFull[i]); LdrEntry->FullDllName.Length = 0; LdrEntry->FullDllName.Buffer = BldrModuleStringsFull[i]; @@ -1256,25 +1258,26 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, /* Find the first \, separating the ARC path from NT path */ BootPath = strchr(CommandLine, '\\'); *BootPath = ANSI_NULL; - strncpy(BldrArcBootPath, CommandLine, 63); + RtlStringCbCopyA(BldrArcBootPath, sizeof(BldrArcBootPath), CommandLine); LoaderBlock->ArcBootDeviceName = BldrArcBootPath; /* The rest of the string is the NT path */ HalPath = strchr(BootPath + 1, ' '); *HalPath = ANSI_NULL; - BldrNtBootPath[0] = '\\'; - strncat(BldrNtBootPath, BootPath + 1, 61); - strcat(BldrNtBootPath,"\\"); + Remaining = sizeof(BldrNtBootPath); + RtlStringCbCopyExA(BldrNtBootPath, Remaining, "\\", &StringEnd, &Remaining, 0); + RtlStringCbCopyExA(StringEnd, Remaining, BootPath + 1, &StringEnd, &Remaining, 0); + RtlStringCbCopyA(StringEnd, Remaining, "\\"); LoaderBlock->NtBootPathName = BldrNtBootPath; /* Set the HAL paths */ - strncpy(BldrArcHalPath, BldrArcBootPath, 63); + RtlStringCbCopyA(BldrArcHalPath, sizeof(BldrArcHalPath), BldrArcBootPath); LoaderBlock->ArcHalDeviceName = BldrArcHalPath; strcpy(BldrNtHalPath, "\\"); LoaderBlock->NtHalPathName = BldrNtHalPath; /* Use this new command line */ - strncpy(LoaderBlock->LoadOptions, HalPath + 2, 255); + RtlStringCbCopyA(LoaderBlock->LoadOptions, 255, HalPath + 2); /* Parse it and change every slash to a space */ BootPath = LoaderBlock->LoadOptions; diff --git a/reactos/ntoskrnl/mm/ARM3/sysldr.c b/reactos/ntoskrnl/mm/ARM3/sysldr.c index 22d0792cc97..443a33d5e63 100644 --- a/reactos/ntoskrnl/mm/ARM3/sysldr.c +++ b/reactos/ntoskrnl/mm/ARM3/sysldr.c @@ -710,9 +710,9 @@ MiSnapThunk(IN PVOID DllBase, NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData; /* Copy the procedure name */ - strncpy(*MissingApi, - (PCHAR)&NameImport->Name[0], - MAXIMUM_FILENAME_LENGTH - 1); + RtlStringCbCopyA(*MissingApi, + MAXIMUM_FILENAME_LENGTH, + (PCHAR)&NameImport->Name[0]); /* Setup name tables */ DPRINT("Import name: %s\n", NameImport->Name); @@ -3000,8 +3000,8 @@ Quickie: /* If we have a file handle, close it */ if (FileHandle) ZwClose(FileHandle); - /* Check if we had a prefix */ - if (NamePrefix) ExFreePool(PrefixName.Buffer); + /* Check if we had a prefix (not supported yet - PrefixName == *FileName now) */ + /* if (NamePrefix) ExFreePool(PrefixName.Buffer); */ /* Free the name buffer and return status */ ExFreePoolWithTag(Buffer, TAG_LDR_WSTR); From 0b986764d468c52017ecdd70022e4eada3327f7d Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 22:34:53 +0000 Subject: [PATCH 75/90] [WIN32K] Make sure strings returned by internal function RegQueryValue are NULL terminated svn path=/trunk/; revision=51139 --- reactos/subsystems/win32/win32k/misc/registry.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/reactos/subsystems/win32/win32k/misc/registry.c b/reactos/subsystems/win32/win32k/misc/registry.c index 86bac347f2f..455aa3f8a36 100644 --- a/reactos/subsystems/win32/win32k/misc/registry.c +++ b/reactos/subsystems/win32/win32k/misc/registry.c @@ -58,7 +58,7 @@ RegQueryValue( ULONG cbInfoSize, cbDataSize; /* Check if the local buffer is sufficient */ - cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *pcbValue; + cbInfoSize = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + *pcbValue; if (cbInfoSize <= sizeof(ajBuffer)) { pInfo = (PVOID)ajBuffer; @@ -89,8 +89,11 @@ RegQueryValue( /* Did we get the right type */ if (pInfo->Type == ulType) { - /* Copy the contents to the caller */ - RtlCopyMemory(pvData, pInfo->Data, min(*pcbValue, cbDataSize)); + /* Copy the contents to the caller. Make sure strings are null terminated */ + if (ulType == REG_SZ || ulType == REG_MULTI_SZ || ulType == REG_EXPAND_SZ) + RtlStringCbCopyNW((LPWSTR)pvData, *pcbValue, (LPWSTR)pInfo->Data, cbDataSize); + else + RtlCopyMemory(pvData, pInfo->Data, cbDataSize); } else Status = STATUS_OBJECT_TYPE_MISMATCH; From 04d67b9ebd7ce0307cb2d8a872002ad5aa0ed20f Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 22:36:37 +0000 Subject: [PATCH 76/90] [WIN32K] Change wcsncpy to safe functions (part 2/x) svn path=/trunk/; revision=51140 --- reactos/subsystems/win32/win32k/ntuser/display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/display.c b/reactos/subsystems/win32/win32k/ntuser/display.c index 7e0f25cf22d..98b93d5ddf7 100644 --- a/reactos/subsystems/win32/win32k/ntuser/display.c +++ b/reactos/subsystems/win32/win32k/ntuser/display.c @@ -309,11 +309,11 @@ UserEnumDisplayDevices( ZwClose(hkey); /* Copy device name, device string and StateFlags */ - wcsncpy(pdispdev->DeviceName, pGraphicsDevice->szWinDeviceName, 32); - wcsncpy(pdispdev->DeviceString, pGraphicsDevice->pwszDescription, 128); + RtlStringCbCopyW(pdispdev->DeviceName, sizeof(pdispdev->DeviceName), pGraphicsDevice->szWinDeviceName); + RtlStringCbCopyW(pdispdev->DeviceString, sizeof(pdispdev->DeviceString), pGraphicsDevice->pwszDescription); pdispdev->StateFlags = pGraphicsDevice->StateFlags; - // FIXME: fill in DEVICE ID + pdispdev->DeviceID[0] = UNICODE_NULL; return STATUS_SUCCESS; } @@ -339,7 +339,7 @@ NtUserEnumDisplayDevices( if (pustrDevice && iDevNum != 0) return FALSE; - dispdev.cb = sizeof(DISPLAY_DEVICEW); + dispdev.cb = sizeof(dispdev); if (pustrDevice) { From eeaccfdfe10a5ff25e93f53baa7d8de17f23fcf6 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 22:45:59 +0000 Subject: [PATCH 77/90] [WIN32K] Forgotten in r51139... svn path=/trunk/; revision=51141 --- reactos/subsystems/win32/win32k/pch.h | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/subsystems/win32/win32k/pch.h b/reactos/subsystems/win32/win32k/pch.h index 479f00a195e..b703d6b868b 100644 --- a/reactos/subsystems/win32/win32k/pch.h +++ b/reactos/subsystems/win32/win32k/pch.h @@ -18,6 +18,7 @@ #include #include #include +#include /* Win32 Headers */ /* FIXME: Defines in winbase.h that we need... */ From 00cfa292298f94555b712a253ec68d165b05b964 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 22:49:30 +0000 Subject: [PATCH 78/90] [WIN32K] Fix GDITAG_LDE/TAG_LDE mess svn path=/trunk/; revision=51142 --- reactos/subsystems/win32/win32k/eng/ldevobj.c | 6 +++--- reactos/subsystems/win32/win32k/include/ldevobj.h | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/reactos/subsystems/win32/win32k/eng/ldevobj.c b/reactos/subsystems/win32/win32k/eng/ldevobj.c index a1c75937333..9f7c1c989fd 100644 --- a/reactos/subsystems/win32/win32k/eng/ldevobj.c +++ b/reactos/subsystems/win32/win32k/eng/ldevobj.c @@ -103,7 +103,7 @@ LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev) ASSERT(pldev && pldev->pGdiDriverInfo == NULL); /* Free the memory */ - ExFreePoolWithTag(pldev, TAG_LDEV); + ExFreePoolWithTag(pldev, GDITAG_LDEV); } PDEVMODEINFO @@ -145,7 +145,7 @@ LDEVOBJ_pdmiGetModes( { /* Could not get modes */ DPRINT1("returned size %ld(%ld)\n", cbSize, pdminfo->cbdevmode); - ExFreePool(pdminfo); + ExFreePoolWithTag(pdminfo, GDITAG_DEVMODE); pdminfo = NULL; } @@ -192,7 +192,7 @@ LDEVOBJ_bLoadImage( pstrPathName->Buffer, Status); /* Free the allocated memory */ - ExFreePoolWithTag(pDriverInfo, TAG_LDEV); + ExFreePoolWithTag(pDriverInfo, GDITAG_LDEV); return FALSE; } diff --git a/reactos/subsystems/win32/win32k/include/ldevobj.h b/reactos/subsystems/win32/win32k/include/ldevobj.h index 963b8332492..633f5feed68 100644 --- a/reactos/subsystems/win32/win32k/include/ldevobj.h +++ b/reactos/subsystems/win32/win32k/include/ldevobj.h @@ -5,9 +5,6 @@ #endif extern IMAGE_DOS_HEADER __ImageBase; - -#define TAG_LDEV 'Gldv' - #define GDI_ENGINE_VERSION DDI_DRIVER_VERSION_NT5_01 typedef enum From 03a8c91d75885f47c18e9991ab5ceb74cb76b75c Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 22:57:46 +0000 Subject: [PATCH 79/90] [WIN32K] wcsncpy -> safe api (part 3/x) svn path=/trunk/; revision=51143 --- reactos/subsystems/win32/win32k/eng/device.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/reactos/subsystems/win32/win32k/eng/device.c b/reactos/subsystems/win32/win32k/eng/device.c index 3e6759499e0..802bcf50e4f 100644 --- a/reactos/subsystems/win32/win32k/eng/device.c +++ b/reactos/subsystems/win32/win32k/eng/device.c @@ -84,12 +84,13 @@ EngpRegisterGraphicsDevice( pGraphicsDevice->FileObject = pFileObject; /* Copy device name */ - wcsncpy(pGraphicsDevice->szNtDeviceName, - pustrDeviceName->Buffer, - sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR)); + RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName, + sizeof(pGraphicsDevice->szNtDeviceName), + pustrDeviceName->Buffer, + pustrDeviceName->Length); /* Create a win device name (FIXME: virtual devices!) */ - swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum); + swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (int)giDevNum); /* Allocate a buffer for the strings */ cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR); @@ -98,6 +99,8 @@ EngpRegisterGraphicsDevice( { DPRINT1("Could not allocate string buffer\n"); ASSERT(FALSE); // FIXME + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); + return NULL; } /* Copy display driver names */ @@ -160,7 +163,7 @@ EngpRegisterGraphicsDevice( if (!pGraphicsDevice->pdevmodeInfo || cModes == 0) { DPRINT1("No devmodes\n"); - ExFreePool(pGraphicsDevice); + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } @@ -172,7 +175,7 @@ EngpRegisterGraphicsDevice( if (!pGraphicsDevice->pDevModeList) { DPRINT1("No devmode list\n"); - ExFreePool(pGraphicsDevice); + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } From 61b6e9119ff21538e56f345b60f8f0293ef6d39d Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Fri, 25 Mar 2011 23:09:06 +0000 Subject: [PATCH 80/90] [WIN32K] wcsncpy -> RtlStringCbCopyW (part 4/x) Avoid unneeded allocation svn path=/trunk/; revision=51144 --- .../win32/win32k/objects/freetype.c | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/freetype.c b/reactos/subsystems/win32/win32k/objects/freetype.c index 4e941ee2047..c7086fd39d4 100644 --- a/reactos/subsystems/win32/win32k/objects/freetype.c +++ b/reactos/subsystems/win32/win32k/objects/freetype.c @@ -1078,12 +1078,16 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI) ExFreePoolWithTag(Otm, GDITAG_TEXT); - wcsncpy(Info->EnumLogFontEx.elfLogFont.lfFaceName, FaceName, LF_FACESIZE); - wcsncpy(Info->EnumLogFontEx.elfFullName, FaceName, LF_FULLFACESIZE); + RtlStringCbCopyW(Info->EnumLogFontEx.elfLogFont.lfFaceName, + sizeof(Info->EnumLogFontEx.elfLogFont.lfFaceName), + FaceName); + RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName, + sizeof(Info->EnumLogFontEx.elfFullName), + FaceName); RtlInitAnsiString(&StyleA, FontGDI->face->style_name); - RtlAnsiStringToUnicodeString(&StyleW, &StyleA, TRUE); - wcsncpy(Info->EnumLogFontEx.elfStyle, StyleW.Buffer, LF_FACESIZE); - RtlFreeUnicodeString(&StyleW); + StyleW.Buffer = Info->EnumLogFontEx.elfStyle; + StyleW.MaximumLength = sizeof(Info->EnumLogFontEx.elfStyle); + RtlAnsiStringToUnicodeString(&StyleW, &StyleA, FALSE); Info->EnumLogFontEx.elfLogFont.lfCharSet = DEFAULT_CHARSET; Info->EnumLogFontEx.elfScript[0] = L'\0'; @@ -1267,8 +1271,10 @@ FontFamilyInfoQueryRegistryCallback(IN PWSTR ValueName, IN ULONG ValueType, if (InfoContext->Count < InfoContext->Size) { InfoContext->Info[InfoContext->Count] = InfoContext->Info[Existing]; - wcsncpy(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName, - RegistryName.Buffer, LF_FACESIZE); + RtlStringCbCopyNW(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName, + sizeof(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName), + RegistryName.Buffer, + RegistryName.Length); } InfoContext->Count++; return STATUS_SUCCESS; @@ -2643,7 +2649,7 @@ FindBestFontFromList(FONTOBJ **FontObj, UINT *MatchScore, LOGFONTW *LogFont, PFONT_ENTRY CurrentEntry; FONTGDI *FontGDI; UINT Score; - +ASSERT(FontObj && MatchScore && LogFont && FaceName && Head); Entry = Head->Flink; while (Entry != Head) { From 6e23217097ce893c6c636ab8d9bdc0825caabba7 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 26 Mar 2011 00:43:56 +0000 Subject: [PATCH 81/90] [Csrss|Win32k] - Enable the desktop class and set the ReactOS variant of csrss back to local desktop class. Now all class tests pass, see bug 4778. svn path=/trunk/; revision=51145 --- reactos/subsystems/win32/csrss/win32csr/desktopbg.c | 2 +- reactos/subsystems/win32/win32k/ntuser/class.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/desktopbg.c b/reactos/subsystems/win32/csrss/win32csr/desktopbg.c index 2c158c57e58..3482cd9dbd6 100644 --- a/reactos/subsystems/win32/csrss/win32csr/desktopbg.c +++ b/reactos/subsystems/win32/csrss/win32csr/desktopbg.c @@ -136,7 +136,7 @@ DtbgInit(VOID) * Create the desktop window class */ Class.cbSize = sizeof(WNDCLASSEXW); - Class.style = CS_GLOBALCLASS; + Class.style = 0; // Local Class Class.lpfnWndProc = DtbgWindowProc; Class.cbClsExtra = 0; Class.cbWndExtra = 0; diff --git a/reactos/subsystems/win32/win32k/ntuser/class.c b/reactos/subsystems/win32/win32k/ntuser/class.c index cc9da7f886b..81e0076be26 100644 --- a/reactos/subsystems/win32/win32k/ntuser/class.c +++ b/reactos/subsystems/win32/win32k/ntuser/class.c @@ -19,15 +19,15 @@ REGISTER_SYSCLASS DefaultServerClasses[] = { -/* { ((PWSTR)((ULONG_PTR)(WORD)(0x8001))), + { ((PWSTR)((ULONG_PTR)(WORD)(0x8001))), CS_GLOBALCLASS|CS_DBLCLKS, NULL, 0, IDC_ARROW, - (HBRUSH)(COLOR_BACKGROUND+1), + (HBRUSH)(COLOR_BACKGROUND + 1), FNID_DESKTOP, ICLS_DESKTOP - },*/ + }, { ((PWSTR)((ULONG_PTR)(WORD)(0x8003))), CS_VREDRAW|CS_HREDRAW|CS_SAVEBITS, NULL, // Use User32 procs From 6af9026458c60838c8615e4ac37a0b6a8151aea9 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 26 Mar 2011 01:20:11 +0000 Subject: [PATCH 82/90] [USER32] Improve formatting svn path=/trunk/; revision=51146 --- reactos/dll/win32/user32/misc/display.c | 406 +++++++++++------------- 1 file changed, 194 insertions(+), 212 deletions(-) diff --git a/reactos/dll/win32/user32/misc/display.c b/reactos/dll/win32/user32/misc/display.c index f00be9b7ad9..196ff76d369 100644 --- a/reactos/dll/win32/user32/misc/display.c +++ b/reactos/dll/win32/user32/misc/display.c @@ -1,29 +1,8 @@ /* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * * PROJECT: ReactOS user32.dll * FILE: lib/user32/misc/dde.c * PURPOSE: DDE * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * UPDATE HISTORY: - * 09-05-2001 CSH Created */ /* INCLUDES ******************************************************************/ @@ -47,49 +26,52 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32); */ BOOL WINAPI EnumDisplayDevicesA( - LPCSTR lpDevice, - DWORD iDevNum, - PDISPLAY_DEVICEA lpDisplayDevice, - DWORD dwFlags) + LPCSTR lpDevice, + DWORD iDevNum, + PDISPLAY_DEVICEA lpDisplayDevice, + DWORD dwFlags) { - BOOL rc; - UNICODE_STRING Device; - DISPLAY_DEVICEW DisplayDeviceW; + BOOL rc; + UNICODE_STRING Device; + DISPLAY_DEVICEW DisplayDeviceW; - if ( !RtlCreateUnicodeStringFromAsciiz ( &Device, (PCSZ)lpDevice ) ) + if (!RtlCreateUnicodeStringFromAsciiz(&Device, (PCSZ)lpDevice)) { - SetLastError ( ERROR_OUTOFMEMORY ); - return FALSE; + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; } - RtlZeroMemory(&DisplayDeviceW, sizeof(DISPLAY_DEVICEW)); - DisplayDeviceW.cb = sizeof(DISPLAY_DEVICEW); - rc = NtUserEnumDisplayDevices ( - &Device, - iDevNum, - &DisplayDeviceW, - dwFlags ); - if (rc) + RtlZeroMemory(&DisplayDeviceW, sizeof(DISPLAY_DEVICEW)); + DisplayDeviceW.cb = sizeof(DISPLAY_DEVICEW); + rc = NtUserEnumDisplayDevices(&Device, + iDevNum, + &DisplayDeviceW, + dwFlags); + if (rc) { - /* Copy result from DisplayDeviceW to lpDisplayDevice. Buffers have the same size so result is always NULL terminated. */ - lpDisplayDevice->StateFlags = DisplayDeviceW.StateFlags; - WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceName, -1, - lpDisplayDevice->DeviceName, sizeof(lpDisplayDevice->DeviceName) / sizeof(lpDisplayDevice->DeviceName[0]), - NULL, NULL); - WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceString, -1, - lpDisplayDevice->DeviceString, sizeof(lpDisplayDevice->DeviceString) / sizeof(lpDisplayDevice->DeviceString[0]), - NULL, NULL); - WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceID, -1, - lpDisplayDevice->DeviceID, sizeof(lpDisplayDevice->DeviceID) / sizeof(lpDisplayDevice->DeviceID[0]), - NULL, NULL); - WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceKey, -1, - lpDisplayDevice->DeviceKey, sizeof(lpDisplayDevice->DeviceKey) / sizeof(lpDisplayDevice->DeviceKey[0]), - NULL, NULL); + /* Copy result from DisplayDeviceW to lpDisplayDevice. Buffers have the same size so result is always NULL terminated. */ + lpDisplayDevice->StateFlags = DisplayDeviceW.StateFlags; + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceName, -1, + lpDisplayDevice->DeviceName, + sizeof(lpDisplayDevice->DeviceName) / sizeof(lpDisplayDevice->DeviceName[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceString, -1, + lpDisplayDevice->DeviceString, + sizeof(lpDisplayDevice->DeviceString) / sizeof(lpDisplayDevice->DeviceString[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceID, -1, + lpDisplayDevice->DeviceID, + sizeof(lpDisplayDevice->DeviceID) / sizeof(lpDisplayDevice->DeviceID[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceKey, -1, + lpDisplayDevice->DeviceKey, + sizeof(lpDisplayDevice->DeviceKey) / sizeof(lpDisplayDevice->DeviceKey[0]), + NULL, NULL); } - RtlFreeUnicodeString ( &Device ); + RtlFreeUnicodeString(&Device); - return rc; + return rc; } @@ -99,23 +81,23 @@ EnumDisplayDevicesA( BOOL WINAPI EnumDisplayDevicesW( - LPCWSTR lpDevice, - DWORD iDevNum, - PDISPLAY_DEVICE lpDisplayDevice, - DWORD dwFlags) + LPCWSTR lpDevice, + DWORD iDevNum, + PDISPLAY_DEVICE lpDisplayDevice, + DWORD dwFlags) { - UNICODE_STRING Device; - BOOL rc; + UNICODE_STRING Device; + BOOL rc; - RtlInitUnicodeString ( &Device, lpDevice ); + RtlInitUnicodeString(&Device, lpDevice); - rc = NtUserEnumDisplayDevices ( - &Device, - iDevNum, - lpDisplayDevice, - dwFlags ); + rc = NtUserEnumDisplayDevices( + &Device, + iDevNum, + lpDisplayDevice, + dwFlags); - return rc; + return rc; } @@ -125,71 +107,71 @@ EnumDisplayDevicesW( BOOL WINAPI EnumDisplayMonitors( - HDC hdc, - LPCRECT lprcClip, - MONITORENUMPROC lpfnEnum, - LPARAM dwData) + HDC hdc, + LPCRECT lprcClip, + MONITORENUMPROC lpfnEnum, + LPARAM dwData) { - INT iCount, i; - HMONITOR *hMonitorList; - LPRECT pRectList; - HANDLE hHeap; + INT iCount, i; + HMONITOR *hMonitorList; + LPRECT pRectList; + HANDLE hHeap; - /* get list of monitors/rects */ - iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0); - if (iCount < 0) + /* get list of monitors/rects */ + iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0); + if (iCount < 0) { - /* FIXME: SetLastError() */ - return FALSE; + /* FIXME: SetLastError() */ + return FALSE; } - if (iCount == 0) + if (iCount == 0) { - return TRUE; + return TRUE; } - hHeap = GetProcessHeap(); - hMonitorList = HeapAlloc(hHeap, 0, sizeof (HMONITOR) * iCount); - if (hMonitorList == NULL) + hHeap = GetProcessHeap(); + hMonitorList = HeapAlloc(hHeap, 0, sizeof (HMONITOR) * iCount); + if (hMonitorList == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; } - pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount); - if (pRectList == NULL) + pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount); + if (pRectList == NULL) { - HeapFree(hHeap, 0, hMonitorList); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + HeapFree(hHeap, 0, hMonitorList); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; } - iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount); - if (iCount <= 0) + iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount); + if (iCount <= 0) { - /* FIXME: SetLastError() */ - HeapFree(hHeap, 0, hMonitorList); - HeapFree(hHeap, 0, pRectList); - return FALSE; + /* FIXME: SetLastError() */ + HeapFree(hHeap, 0, hMonitorList); + HeapFree(hHeap, 0, pRectList); + return FALSE; } - /* enumerate list */ - for (i = 0; i < iCount; i++) + /* enumerate list */ + for (i = 0; i < iCount; i++) { - HMONITOR hMonitor = hMonitorList[i]; - LPRECT pMonitorRect = pRectList + i; - HDC hMonitorDC = NULL; + HMONITOR hMonitor = hMonitorList[i]; + LPRECT pMonitorRect = pRectList + i; + HDC hMonitorDC = NULL; - if (hdc != NULL) + if (hdc != NULL) { - /* make monitor DC */ - hMonitorDC = hdc; + /* make monitor DC */ + hMonitorDC = hdc; } - if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData)) - break; + if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData)) + break; } - HeapFree(hHeap, 0, hMonitorList); - HeapFree(hHeap, 0, pRectList); - return TRUE; + HeapFree(hHeap, 0, hMonitorList); + HeapFree(hHeap, 0, pRectList); + return TRUE; } @@ -240,13 +222,13 @@ EnumDisplaySettingsExA( COPYN(dmDriverVersion); switch (lpDevMode->dmSize) { - case SIZEOF_DEVMODEA_300: - case SIZEOF_DEVMODEA_400: - case SIZEOF_DEVMODEA_500: - break; - default: - lpDevMode->dmSize = SIZEOF_DEVMODEA_300; - break; + case SIZEOF_DEVMODEA_300: + case SIZEOF_DEVMODEA_400: + case SIZEOF_DEVMODEA_500: + break; + default: + lpDevMode->dmSize = SIZEOF_DEVMODEA_300; + break; } COPYN(dmDriverExtra); COPYN(dmFields); @@ -295,11 +277,11 @@ EnumDisplaySettingsExA( BOOL WINAPI EnumDisplaySettingsA( - LPCSTR lpszDeviceName, - DWORD iModeNum, - LPDEVMODEA lpDevMode) + LPCSTR lpszDeviceName, + DWORD iModeNum, + LPDEVMODEA lpDevMode) { - return EnumDisplaySettingsExA ( lpszDeviceName, iModeNum, lpDevMode, 0 ); + return EnumDisplaySettingsExA ( lpszDeviceName, iModeNum, lpDevMode, 0 ); } @@ -335,11 +317,11 @@ EnumDisplaySettingsExW( BOOL WINAPI EnumDisplaySettingsW( - LPCWSTR lpszDeviceName, - DWORD iModeNum, - LPDEVMODEW lpDevMode) + LPCWSTR lpszDeviceName, + DWORD iModeNum, + LPDEVMODEW lpDevMode) { - return EnumDisplaySettingsExW ( lpszDeviceName, iModeNum, lpDevMode, 0 ); + return EnumDisplaySettingsExW ( lpszDeviceName, iModeNum, lpDevMode, 0 ); } @@ -349,40 +331,40 @@ EnumDisplaySettingsW( BOOL WINAPI GetMonitorInfoA( - HMONITOR hMonitor, - LPMONITORINFO lpmi) + HMONITOR hMonitor, + LPMONITORINFO lpmi) { - if (lpmi->cbSize == sizeof (MONITORINFO)) + if (lpmi->cbSize == sizeof (MONITORINFO)) { - return NtUserGetMonitorInfo(hMonitor, lpmi); + return NtUserGetMonitorInfo(hMonitor, lpmi); } - else if (lpmi->cbSize != sizeof (MONITORINFOEXA)) + else if (lpmi->cbSize != sizeof (MONITORINFOEXA)) { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } - else + else { - MONITORINFOEXW miExW; - INT res; + MONITORINFOEXW miExW; + INT res; - miExW.cbSize = sizeof (MONITORINFOEXW); - if (!NtUserGetMonitorInfo(hMonitor, (LPMONITORINFO)&miExW)) + miExW.cbSize = sizeof (MONITORINFOEXW); + if (!NtUserGetMonitorInfo(hMonitor, (LPMONITORINFO)&miExW)) { - return FALSE; + return FALSE; } - memcpy(lpmi, &miExW, sizeof (MONITORINFO)); - res = WideCharToMultiByte(CP_THREAD_ACP, 0, miExW.szDevice, -1, - ((LPMONITORINFOEXA)lpmi)->szDevice, CCHDEVICENAME, - NULL, NULL); - if (res == 0) + memcpy(lpmi, &miExW, sizeof (MONITORINFO)); + res = WideCharToMultiByte(CP_THREAD_ACP, 0, miExW.szDevice, -1, + ((LPMONITORINFOEXA)lpmi)->szDevice, CCHDEVICENAME, + NULL, NULL); + if (res == 0) { - WARN("WideCharToMultiByte() failed!\n"); - return FALSE; + WARN("WideCharToMultiByte() failed!\n"); + return FALSE; } } - return TRUE; + return TRUE; } @@ -392,10 +374,10 @@ GetMonitorInfoA( BOOL WINAPI GetMonitorInfoW( - HMONITOR hMonitor, - LPMONITORINFO lpmi) + HMONITOR hMonitor, + LPMONITORINFO lpmi) { - return NtUserGetMonitorInfo(hMonitor, lpmi); + return NtUserGetMonitorInfo(hMonitor, lpmi); } @@ -405,10 +387,10 @@ GetMonitorInfoW( HMONITOR WINAPI MonitorFromPoint( - IN POINT ptPoint, - IN DWORD dwFlags ) + IN POINT ptPoint, + IN DWORD dwFlags ) { - return NtUserMonitorFromPoint(ptPoint, dwFlags); + return NtUserMonitorFromPoint(ptPoint, dwFlags); } @@ -418,10 +400,10 @@ MonitorFromPoint( HMONITOR WINAPI MonitorFromRect( - IN LPCRECT lpcRect, - IN DWORD dwFlags ) + IN LPCRECT lpcRect, + IN DWORD dwFlags ) { - return NtUserMonitorFromRect(lpcRect, dwFlags); + return NtUserMonitorFromRect(lpcRect, dwFlags); } @@ -431,10 +413,10 @@ MonitorFromRect( HMONITOR WINAPI MonitorFromWindow( - IN HWND hWnd, - IN DWORD dwFlags ) + IN HWND hWnd, + IN DWORD dwFlags ) { - return NtUserMonitorFromWindow(hWnd, dwFlags); + return NtUserMonitorFromWindow(hWnd, dwFlags); } @@ -444,46 +426,46 @@ MonitorFromWindow( LONG WINAPI ChangeDisplaySettingsExA( - LPCSTR lpszDeviceName, - LPDEVMODEA lpDevMode, - HWND hwnd, - DWORD dwflags, - LPVOID lParam) + LPCSTR lpszDeviceName, + LPDEVMODEA lpDevMode, + HWND hwnd, + DWORD dwflags, + LPVOID lParam) { - LONG rc; - UNICODE_STRING DeviceName; - PUNICODE_STRING pDeviceName = &DeviceName; + LONG rc; + UNICODE_STRING DeviceName; + PUNICODE_STRING pDeviceName = &DeviceName; - if (lpszDeviceName != NULL) + if (lpszDeviceName != NULL) { - if ( !RtlCreateUnicodeStringFromAsciiz ( pDeviceName, (PCSZ)lpszDeviceName ) ) + if (!RtlCreateUnicodeStringFromAsciiz(pDeviceName, (PCSZ)lpszDeviceName)) { - SetLastError ( ERROR_OUTOFMEMORY ); - return DISP_CHANGE_BADPARAM; /* FIXME what to return? */ + SetLastError(ERROR_OUTOFMEMORY); + return DISP_CHANGE_BADPARAM; /* FIXME what to return? */ } } - else - pDeviceName = NULL; + else + pDeviceName = NULL; - if (lpDevMode != NULL) - { - LPDEVMODEW pDevModeW; - pDevModeW = GdiConvertToDevmodeW(lpDevMode); - if(pDevModeW) + if (lpDevMode != NULL) { - rc = NtUserChangeDisplaySettings ( pDeviceName, pDevModeW, hwnd, dwflags, lParam ); - RtlFreeHeap(GetProcessHeap(), 0, pDevModeW); + LPDEVMODEW pDevModeW; + pDevModeW = GdiConvertToDevmodeW(lpDevMode); + if(pDevModeW) + { + rc = NtUserChangeDisplaySettings(pDeviceName, pDevModeW, hwnd, dwflags, lParam); + RtlFreeHeap(GetProcessHeap(), 0, pDevModeW); + } + else + rc = DISP_CHANGE_SUCCESSFUL; } else - rc = DISP_CHANGE_SUCCESSFUL; - } - else - rc = NtUserChangeDisplaySettings ( pDeviceName, NULL, hwnd, dwflags, lParam ); + rc = NtUserChangeDisplaySettings(pDeviceName, NULL, hwnd, dwflags, lParam); - if (lpszDeviceName != NULL) - RtlFreeUnicodeString ( &DeviceName ); + if (lpszDeviceName != NULL) + RtlFreeUnicodeString(&DeviceName); - return rc; + return rc; } @@ -493,12 +475,12 @@ ChangeDisplaySettingsExA( LONG WINAPI ChangeDisplaySettingsA( - LPDEVMODEA lpDevMode, - DWORD dwflags) + LPDEVMODEA lpDevMode, + DWORD dwflags) { - if(lpDevMode) - lpDevMode->dmDriverExtra = 0; - return ChangeDisplaySettingsExA ( NULL, lpDevMode, NULL, dwflags, 0 ); + if(lpDevMode) + lpDevMode->dmDriverExtra = 0; + return ChangeDisplaySettingsExA ( NULL, lpDevMode, NULL, dwflags, 0 ); } @@ -508,24 +490,24 @@ ChangeDisplaySettingsA( LONG WINAPI ChangeDisplaySettingsExW( - LPCWSTR lpszDeviceName, - LPDEVMODEW lpDevMode, - HWND hwnd, - DWORD dwflags, - LPVOID lParam) + LPCWSTR lpszDeviceName, + LPDEVMODEW lpDevMode, + HWND hwnd, + DWORD dwflags, + LPVOID lParam) { - LONG rc; - UNICODE_STRING DeviceName; - PUNICODE_STRING pDeviceName = &DeviceName; + LONG rc; + UNICODE_STRING DeviceName; + PUNICODE_STRING pDeviceName = &DeviceName; - if (lpszDeviceName != NULL) - RtlInitUnicodeString ( pDeviceName, lpszDeviceName ); - else - pDeviceName = NULL; + if (lpszDeviceName != NULL) + RtlInitUnicodeString(pDeviceName, lpszDeviceName); + else + pDeviceName = NULL; - rc = NtUserChangeDisplaySettings ( pDeviceName, lpDevMode, hwnd, dwflags, lParam ); + rc = NtUserChangeDisplaySettings(pDeviceName, lpDevMode, hwnd, dwflags, lParam); - return rc; + return rc; } @@ -535,10 +517,10 @@ ChangeDisplaySettingsExW( LONG WINAPI ChangeDisplaySettingsW( - LPDEVMODEW lpDevMode, - DWORD dwflags) + LPDEVMODEW lpDevMode, + DWORD dwflags) { - if(lpDevMode) - lpDevMode->dmDriverExtra = 0; - return ChangeDisplaySettingsExW ( NULL, lpDevMode, NULL, dwflags, 0 ); + if(lpDevMode) + lpDevMode->dmDriverExtra = 0; + return ChangeDisplaySettingsExW(NULL, lpDevMode, NULL, dwflags, 0); } From b294b7d77462873fbefc0e93bb98990e7c9289fc Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 26 Mar 2011 02:10:04 +0000 Subject: [PATCH 83/90] [GDI32] - Patch by Thomas Faber: GetTextExtentPoint32 must not assume null termination of lpString. svn path=/trunk/; revision=51147 --- reactos/dll/win32/gdi32/objects/text.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/gdi32/objects/text.c b/reactos/dll/win32/gdi32/objects/text.c index e434532fc43..d1bb5d5b4d5 100644 --- a/reactos/dll/win32/gdi32/objects/text.c +++ b/reactos/dll/win32/gdi32/objects/text.c @@ -261,7 +261,8 @@ GetTextExtentPoint32A( UNICODE_STRING StringU; BOOL ret; - RtlInitAnsiString(&StringA, (LPSTR)lpString); + StringA.Buffer = (LPSTR)lpString; + StringA.Length = cchString; RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE); ret = GetTextExtentPoint32W(hdc, StringU.Buffer, cchString, lpSize); From 00a64f39cb9bcbe60cb7c057a288f06b83acfc9c Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 26 Mar 2011 05:31:59 +0000 Subject: [PATCH 84/90] [User32] - Cleanup edit and add back missing break in combo. svn path=/trunk/; revision=51148 --- reactos/dll/win32/user32/controls/combo.c | 1 + reactos/dll/win32/user32/controls/edit.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/user32/controls/combo.c b/reactos/dll/win32/user32/controls/combo.c index 422953195c4..adeac610d78 100644 --- a/reactos/dll/win32/user32/controls/combo.c +++ b/reactos/dll/win32/user32/controls/combo.c @@ -2232,6 +2232,7 @@ LRESULT WINAPI ComboWndProc_common( HWND hwnd, UINT message, case CB_LIMITTEXT: if( lphc->wState & CBF_EDIT ) return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam); + break; // ReactOS!!! removed at revision 38715 case WM_UPDATEUISTATE: if (unicode) diff --git a/reactos/dll/win32/user32/controls/edit.c b/reactos/dll/win32/user32/controls/edit.c index 65f36797f63..b07830f3ce9 100644 --- a/reactos/dll/win32/user32/controls/edit.c +++ b/reactos/dll/win32/user32/controls/edit.c @@ -4477,8 +4477,8 @@ LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP { NtUserSetWindowFNID(hwnd, FNID_EDIT); } - } -#endif + } +#endif TRACE("hwnd=%p msg=%x (%s) wparam=%lx lparam=%lx\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), wParam, lParam); From 7e914b6e08da7c67d256912621153c3d7d5f23af Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Sat, 26 Mar 2011 15:12:23 +0000 Subject: [PATCH 85/90] [NDIS] Correct Length value in case string is truncated svn path=/trunk/; revision=51159 --- reactos/drivers/network/ndis/ndis/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/drivers/network/ndis/ndis/config.c b/reactos/drivers/network/ndis/ndis/config.c index b95f1e01060..f0227c71fd6 100644 --- a/reactos/drivers/network/ndis/ndis/config.c +++ b/reactos/drivers/network/ndis/ndis/config.c @@ -841,7 +841,7 @@ NdisOpenConfigurationKeyByIndex( /* should i fail instead if the passed-in string isn't long enough? */ wcsncpy(KeyName->Buffer, KeyInformation->Name, KeyName->MaximumLength/sizeof(WCHAR)); - KeyName->Length = (USHORT)KeyInformation->NameLength; + KeyName->Length = (USHORT)min(KeyInformation->NameLength, KeyName->MaximumLength); InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE, ConfigurationHandle, NULL); From 68af0e9cd14a722a23cb2b66b33c7319f7d84d99 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Sat, 26 Mar 2011 15:23:10 +0000 Subject: [PATCH 86/90] [GDI32_APITEST] Improve CreatePen and GetCurrentObject tests svn path=/trunk/; revision=51160 --- rostests/apitests/gdi32/CreatePen.c | 68 +++++++---- rostests/apitests/gdi32/GetCurrentObject.c | 129 +++++++++++++-------- 2 files changed, 121 insertions(+), 76 deletions(-) diff --git a/rostests/apitests/gdi32/CreatePen.c b/rostests/apitests/gdi32/CreatePen.c index d45d17194be..2c791569b85 100644 --- a/rostests/apitests/gdi32/CreatePen.c +++ b/rostests/apitests/gdi32/CreatePen.c @@ -19,50 +19,68 @@ void Test_CreatePen() SetLastError(ERROR_SUCCESS); hPen = CreatePen(PS_DASHDOT, 5, RGB(1,2,3)); - ok(hPen != 0, "\n"); + ok(hPen != 0, "CreatePen failed\n"); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Test if we have a PEN */ - ok(GDI_HANDLE_GET_TYPE(hPen) == GDI_OBJECT_TYPE_PEN, "\n"); + ok(GDI_HANDLE_GET_TYPE(hPen) == GDI_OBJECT_TYPE_PEN, "Expected GDI_OBJECT_TYPE_PEN, got %lu\n", GDI_HANDLE_GET_TYPE(hPen)); - GetObject(hPen, sizeof(logpen), &logpen); - ok(logpen.lopnStyle == PS_DASHDOT, "\n"); - ok(logpen.lopnWidth.x == 5, "\n"); - ok(logpen.lopnColor == RGB(1,2,3), "\n"); - DeleteObject(hPen); + ok(GetObject(hPen, sizeof(logpen), &logpen), "GetObject failed\n"); + ok(logpen.lopnStyle == PS_DASHDOT, "Expected PS_DASHDOT, got %u\n", logpen.lopnStyle); + ok(logpen.lopnWidth.x == 5, "Expected 5, got %lu\n", logpen.lopnWidth.x); + ok(logpen.lopnColor == RGB(1,2,3), "Expected %x, got %x\n", (unsigned)RGB(1,2,3), (unsigned)logpen.lopnColor); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); + if(hPen) + ok(DeleteObject(hPen), "DeleteObject failed\n"); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* PS_GEOMETRIC | PS_DASHDOT = 0x00001011 will become PS_SOLID */ + SetLastError(ERROR_SUCCESS); logpen.lopnStyle = 22; hPen = CreatePen(PS_GEOMETRIC | PS_DASHDOT, 5, RGB(1,2,3)); - ok(hPen != 0, "\n"); - GetObject(hPen, sizeof(logpen), &logpen); - ok(logpen.lopnStyle == PS_SOLID, "\n"); - DeleteObject(hPen); + ok(hPen != 0, "CreatePen failed\n"); + ok(GetObject(hPen, sizeof(logpen), &logpen), "GetObject failed\n"); + ok(logpen.lopnStyle == PS_SOLID, "Expected PS_SOLID, got %u\n", logpen.lopnStyle); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); + if(hPen) + ok(DeleteObject(hPen), "DeleteObject failed\n"); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* PS_USERSTYLE will become PS_SOLID */ logpen.lopnStyle = 22; + SetLastError(ERROR_SUCCESS); hPen = CreatePen(PS_USERSTYLE, 5, RGB(1,2,3)); - ok(hPen != 0, "\n"); - GetObject(hPen, sizeof(logpen), &logpen); - ok(logpen.lopnStyle == PS_SOLID, "\n"); - DeleteObject(hPen); + ok(hPen != 0, "CreatePen failed\n"); + ok(GetObject(hPen, sizeof(logpen), &logpen), "GetObject failed\n"); + ok(logpen.lopnStyle == PS_SOLID, "Expected PS_SOLID, got %u\n", logpen.lopnStyle); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); + if(hPen) + ok(DeleteObject(hPen), "DeleteObject failed\n"); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* PS_ALTERNATE will become PS_SOLID */ logpen.lopnStyle = 22; + SetLastError(ERROR_SUCCESS); hPen = CreatePen(PS_ALTERNATE, 5, RGB(1,2,3)); - ok(hPen != 0, "\n"); - GetObject(hPen, sizeof(logpen), &logpen); - ok(logpen.lopnStyle == PS_SOLID, "\n"); - DeleteObject(hPen); + ok(hPen != 0, "CreatePen failed\n"); + ok(GetObject(hPen, sizeof(logpen), &logpen), "GetObject failed\n"); + ok(logpen.lopnStyle == PS_SOLID, "Expected PS_SOLID, got %u\n", logpen.lopnStyle); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); + if(hPen) + ok(DeleteObject(hPen), "DeleteObject failed\n"); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* PS_INSIDEFRAME is ok */ logpen.lopnStyle = 22; + SetLastError(ERROR_SUCCESS); hPen = CreatePen(PS_INSIDEFRAME, 5, RGB(1,2,3)); - ok(hPen != 0, "\n"); - GetObject(hPen, sizeof(logpen), &logpen); - ok(logpen.lopnStyle == PS_INSIDEFRAME, "\n"); - DeleteObject(hPen); - - ok(GetLastError() == ERROR_SUCCESS, "\n"); + ok(hPen != 0, "CreatePen failed\n"); + ok(GetObject(hPen, sizeof(logpen), &logpen), "GetObject failed\n"); + ok(logpen.lopnStyle == PS_INSIDEFRAME, "Expected PS_INSIDEFRAME, got %u\n", logpen.lopnStyle); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); + if(hPen) + ok(DeleteObject(hPen), "DeleteObject failed\n"); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); } START_TEST(CreatePen) diff --git a/rostests/apitests/gdi32/GetCurrentObject.c b/rostests/apitests/gdi32/GetCurrentObject.c index c8389ebf20e..d56eb2e6c5e 100644 --- a/rostests/apitests/gdi32/GetCurrentObject.c +++ b/rostests/apitests/gdi32/GetCurrentObject.c @@ -17,6 +17,7 @@ void Test_GetCurrentObject() HWND hWnd; HDC hDC; HBITMAP hBmp; + HGDIOBJ hObj; /* Create a window */ hWnd = CreateWindowW(L"BUTTON", L"TestWindow", WS_OVERLAPPEDWINDOW | WS_VISIBLE, @@ -27,121 +28,147 @@ void Test_GetCurrentObject() /* Test NULL DC */ SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(NULL, 0) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(NULL, 0); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(NULL, OBJ_BITMAP) == 0, "\n"); - ok(GetCurrentObject(NULL, OBJ_BRUSH) == 0, "\n"); - ok(GetCurrentObject(NULL, OBJ_COLORSPACE) == 0, "\n"); - ok(GetCurrentObject(NULL, OBJ_FONT) == 0, "\n"); - ok(GetCurrentObject(NULL, OBJ_PAL) == 0, "\n"); - ok(GetCurrentObject(NULL, OBJ_PEN) == 0, "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(NULL, OBJ_BITMAP); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + hObj = GetCurrentObject(NULL, OBJ_BRUSH); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + hObj = GetCurrentObject(NULL, OBJ_COLORSPACE); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + hObj = GetCurrentObject(NULL, OBJ_FONT); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + hObj = GetCurrentObject(NULL, OBJ_PAL); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + hObj = GetCurrentObject(NULL, OBJ_PEN); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Test invalid DC handle */ SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject((HDC)-123, 0) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject((HDC)-123, 0); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject((HDC)-123, OBJ_BITMAP) == 0, "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject((HDC)-123, OBJ_BITMAP); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Test invalid types */ SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, 0) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(hDC, 0); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, 3) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(hDC, 3); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, 4) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(hDC, 4); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, 8) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(hDC, 8); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, 9) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(hDC, 9); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, 10) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(hDC, 10); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, 12) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(hDC, 12); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, 13) == 0, "\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); + hObj = GetCurrentObject(hDC, 13); + ok(hObj == 0, "Expected 0, got %p\n", hObj); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError()); /* Default bitmap */ SetLastError(ERROR_SUCCESS); hBmp = GetCurrentObject(hDC, OBJ_BITMAP); - ok(GDI_HANDLE_GET_TYPE(hBmp) == GDI_OBJECT_TYPE_BITMAP, "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + ok(GDI_HANDLE_GET_TYPE(hBmp) == GDI_OBJECT_TYPE_BITMAP, "Expected GDI_OBJECT_TYPE_BITMAP, got %lu\n", GDI_HANDLE_GET_TYPE(hBmp)); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Other bitmap */ SetLastError(ERROR_SUCCESS); SelectObject(hDC, GetStockObject(21)); ok(hBmp == GetCurrentObject(hDC, OBJ_BITMAP), "\n"); - ok(GDI_HANDLE_GET_TYPE(hBmp) == GDI_OBJECT_TYPE_BITMAP, "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + ok(GDI_HANDLE_GET_TYPE(hBmp) == GDI_OBJECT_TYPE_BITMAP, "Expected GDI_OBJECT_TYPE_BITMAP, got %lu\n", GDI_HANDLE_GET_TYPE(hBmp)); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Default brush */ SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, OBJ_BRUSH) == GetStockObject(WHITE_BRUSH), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_BRUSH); + ok(hObj == GetStockObject(WHITE_BRUSH), "Expected %p, got %p\n", GetStockObject(WHITE_BRUSH), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Other brush */ SetLastError(ERROR_SUCCESS); SelectObject(hDC, GetStockObject(BLACK_BRUSH)); - ok(GetCurrentObject(hDC, OBJ_BRUSH) == GetStockObject(BLACK_BRUSH), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_BRUSH); + ok(hObj == GetStockObject(BLACK_BRUSH), "Expected %p, got %p\n", GetStockObject(BLACK_BRUSH), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Default colorspace */ SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, OBJ_COLORSPACE) == GetStockObject(20), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_COLORSPACE); + ok(hObj == GetStockObject(20), "Expected %p, got %p\n", GetStockObject(20), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Default font */ SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, OBJ_FONT) == GetStockObject(SYSTEM_FONT), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_FONT); + ok(hObj == GetStockObject(SYSTEM_FONT), "Expected %p, got %p\n", GetStockObject(SYSTEM_FONT), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Other font */ SetLastError(ERROR_SUCCESS); SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT)); - ok(GetCurrentObject(hDC, OBJ_FONT) == GetStockObject(DEFAULT_GUI_FONT), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_FONT); + ok(hObj == GetStockObject(DEFAULT_GUI_FONT), "Expected %p, got %p\n", GetStockObject(DEFAULT_GUI_FONT), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Default palette */ SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, OBJ_PAL) == GetStockObject(DEFAULT_PALETTE), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_PAL); + ok(hObj == GetStockObject(DEFAULT_PALETTE), "Expected %p, got %p\n", GetStockObject(DEFAULT_PALETTE), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Default pen */ SetLastError(ERROR_SUCCESS); - ok(GetCurrentObject(hDC, OBJ_PEN) == GetStockObject(BLACK_PEN), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_PEN); + ok(hObj == GetStockObject(BLACK_PEN), "Expected %p, got %p\n", GetStockObject(BLACK_PEN), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* Other pen */ SetLastError(ERROR_SUCCESS); SelectObject(hDC, GetStockObject(WHITE_PEN)); - ok(GetCurrentObject(hDC, OBJ_PEN) == GetStockObject(WHITE_PEN), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_PEN); + ok(hObj == GetStockObject(WHITE_PEN), "Expected %p, got %p\n", GetStockObject(WHITE_PEN), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); /* DC pen */ SetLastError(ERROR_SUCCESS); SelectObject(hDC, GetStockObject(DC_PEN)); - ok(GetCurrentObject(hDC, OBJ_PEN) == GetStockObject(DC_PEN), "\n"); - ok(GetLastError() == ERROR_SUCCESS, "\n"); + hObj = GetCurrentObject(hDC, OBJ_PEN); + ok(hObj == GetStockObject(DC_PEN), "Expected %p, got %p\n", GetStockObject(DC_PEN), hObj); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); ReleaseDC(hWnd, hDC); DestroyWindow(hWnd); From 291012914db01c3f07d03bdb6052cec76d1d4fc0 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Sat, 26 Mar 2011 15:24:05 +0000 Subject: [PATCH 87/90] [GDI32] Fix gdi32:CreatePen apitest svn path=/trunk/; revision=51161 --- reactos/dll/win32/gdi32/misc/misc.c | 46 ++++++++++------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/reactos/dll/win32/gdi32/misc/misc.c b/reactos/dll/win32/gdi32/misc/misc.c index 408a658d72e..8fedb8fb820 100644 --- a/reactos/dll/win32/gdi32/misc/misc.c +++ b/reactos/dll/win32/gdi32/misc/misc.c @@ -124,38 +124,24 @@ BOOL GdiIsHandleValid(HGDIOBJ hGdiObj) BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData) { PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj); - if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType && - ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) == - GDI_HANDLE_GET_TYPE(hGdiObj)) + + /* Check if twe have the correct type */ + if (GDI_HANDLE_GET_TYPE(hGdiObj) != ObjectType || + ((Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK) != ObjectType || + (Entry->Type & GDI_ENTRY_BASETYPE_MASK) != (ObjectType & GDI_ENTRY_BASETYPE_MASK)) { - HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1); - if(pid == NULL || pid == CurrentProcessId) - { - // - // Need to test if we have Read & Write access to the VM address space. - // - BOOL Result = TRUE; - if(Entry->UserData) - { - volatile CHAR *Current = (volatile CHAR*)Entry->UserData; - _SEH2_TRY - { - *Current = *Current; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Result = FALSE; - } - _SEH2_END - } - else - Result = FALSE; // Can not be zero. - if (Result) *UserData = Entry->UserData; - return Result; - } + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + + /* Check if we are the owner */ + if ((HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1) != CurrentProcessId) + { + return FALSE; + } + + *UserData = Entry->UserData; + return TRUE; } PLDC From 299f6a78269dfc2a2111642e4672ca1b5ed323db Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Sat, 26 Mar 2011 17:49:55 +0000 Subject: [PATCH 88/90] [VIDEOPRT] Add missing check Don't assume UNICODE_STRING is NULL-terminated svn path=/trunk/; revision=51163 --- reactos/drivers/video/videoprt/videoprt.c | 94 ++++++++++++++--------- 1 file changed, 56 insertions(+), 38 deletions(-) diff --git a/reactos/drivers/video/videoprt/videoprt.c b/reactos/drivers/video/videoprt/videoprt.c index e2e8df2ca77..73976f8b39d 100644 --- a/reactos/drivers/video/videoprt/videoprt.c +++ b/reactos/drivers/video/videoprt/videoprt.c @@ -83,27 +83,43 @@ IntCreateRegistryPath( static WCHAR ControlSet[] = L"CONTROLSET"; static WCHAR Insert1[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\"; static WCHAR Insert2[] = L"\\Device0"; - LPWSTR ProfilePath = NULL; BOOLEAN Valid; - PWCHAR AfterControlSet; + UNICODE_STRING AfterControlSet; - Valid = (0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem, - wcslen(RegistryMachineSystem))); + AfterControlSet = *DriverRegistryPath; + /* Check if path begins with \\REGISTRY\\MACHINE\\SYSTEM\\ */ + Valid = (DriverRegistryPath->Length > sizeof(RegistryMachineSystem) && + 0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem, + wcslen(RegistryMachineSystem))); + if (Valid) { - AfterControlSet = DriverRegistryPath->Buffer + wcslen(RegistryMachineSystem); - if (0 == _wcsnicmp(AfterControlSet, CurrentControlSet, wcslen(CurrentControlSet))) + AfterControlSet.Buffer += wcslen(RegistryMachineSystem); + AfterControlSet.Length -= sizeof(RegistryMachineSystem) - sizeof(UNICODE_NULL); + + /* Check if path contains CURRENTCONTROLSET */ + if (AfterControlSet.Length > sizeof(CurrentControlSet) && + 0 == _wcsnicmp(AfterControlSet.Buffer, CurrentControlSet, wcslen(CurrentControlSet))) { - AfterControlSet += wcslen(CurrentControlSet); + AfterControlSet.Buffer += wcslen(CurrentControlSet); + AfterControlSet.Length -= sizeof(CurrentControlSet) - sizeof(UNICODE_NULL); } - else if (0 == _wcsnicmp(AfterControlSet, ControlSet, wcslen(ControlSet))) + /* Check if path contains CONTROLSETnum */ + else if (AfterControlSet.Length > sizeof(ControlSet) && + 0 == _wcsnicmp(AfterControlSet.Buffer, ControlSet, wcslen(ControlSet))) { - AfterControlSet += wcslen(ControlSet); - while (L'0' <= *AfterControlSet && L'9' <= *AfterControlSet) + AfterControlSet.Buffer += wcslen(ControlSet); + AfterControlSet.Length -= sizeof(ControlSet) - sizeof(UNICODE_NULL); + while (AfterControlSet.Length > 0 && + L'0' <= *AfterControlSet.Buffer && + L'9' <= *AfterControlSet.Buffer) { - AfterControlSet++; + AfterControlSet.Buffer++; + AfterControlSet.Length -= sizeof(WCHAR); } - Valid = (L'\\' == *AfterControlSet); - AfterControlSet++; + Valid = (AfterControlSet.Length > 0 && L'\\' == *AfterControlSet.Buffer); + AfterControlSet.Buffer++; + AfterControlSet.Length -= sizeof(WCHAR); + AfterControlSet.MaximumLength = AfterControlSet.Length; } else { @@ -113,18 +129,26 @@ IntCreateRegistryPath( if (Valid) { - ProfilePath = ExAllocatePoolWithTag(PagedPool, - (wcslen(DriverRegistryPath->Buffer) + - wcslen(Insert1) + wcslen(Insert2) + 1) * sizeof(WCHAR), - TAG_VIDEO_PORT); - if (NULL != ProfilePath) + DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert1) + sizeof(Insert2); + DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(PagedPool, + DeviceRegistryPath->MaximumLength, + TAG_VIDEO_PORT); + if (NULL != DeviceRegistryPath->Buffer) { - wcsncpy(ProfilePath, DriverRegistryPath->Buffer, AfterControlSet - DriverRegistryPath->Buffer); - wcscpy(ProfilePath + (AfterControlSet - DriverRegistryPath->Buffer), Insert1); - wcscat(ProfilePath, AfterControlSet); - wcscat(ProfilePath, Insert2); - - Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ProfilePath)); + /* Build device path */ + wcsncpy(DeviceRegistryPath->Buffer, + DriverRegistryPath->Buffer, + AfterControlSet.Buffer - DriverRegistryPath->Buffer); + DeviceRegistryPath->Length = (AfterControlSet.Buffer - DriverRegistryPath->Buffer) * sizeof(WCHAR); + RtlAppendUnicodeToString(DeviceRegistryPath, Insert1); + RtlAppendUnicodeStringToString(DeviceRegistryPath, &AfterControlSet); + RtlAppendUnicodeToString(DeviceRegistryPath, Insert2); + + /* Check if registry key exists */ + Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DriverRegistryPath->Buffer)); + + if(!Valid) + ExFreePoolWithTag(DeviceRegistryPath->Buffer, TAG_VIDEO_PORT); } else { @@ -136,28 +160,22 @@ IntCreateRegistryPath( WARN_(VIDEOPRT, "Unparsable registry path %wZ", DriverRegistryPath); } - if (Valid) + /* If path doesn't point to *ControlSet*, use DriverRegistryPath directly */ + if (!Valid) { - RtlInitUnicodeString(DeviceRegistryPath, ProfilePath); - } - else - { - if (ProfilePath) - ExFreePoolWithTag(ProfilePath, TAG_VIDEO_PORT); - - DeviceRegistryPath->Length = - DeviceRegistryPath->MaximumLength = - DriverRegistryPath->Length + (9 * sizeof(WCHAR)); - DeviceRegistryPath->Length -= sizeof(WCHAR); + DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert2); DeviceRegistryPath->Buffer = ExAllocatePoolWithTag( NonPagedPool, DeviceRegistryPath->MaximumLength, TAG_VIDEO_PORT); + if (!DeviceRegistryPath->Buffer) return STATUS_NO_MEMORY; - swprintf(DeviceRegistryPath->Buffer, L"%s\\Device0", - DriverRegistryPath->Buffer); + + RtlCopyUnicodeString(DeviceRegistryPath, DriverRegistryPath); + RtlAppendUnicodeToString(DeviceRegistryPath, Insert2); } + return STATUS_SUCCESS; } From ac4083c6d774348e2d58efebe356221b6d986366 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 26 Mar 2011 20:07:09 +0000 Subject: [PATCH 89/90] Disable some misleading service tests because a test cannot determine wheter or not the number of active or inactive services is correct. svn path=/trunk/; revision=51164 --- rostests/winetests/advapi32/service.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rostests/winetests/advapi32/service.c b/rostests/winetests/advapi32/service.c index 605f3842de7..aae8c6ea9b1 100644 --- a/rostests/winetests/advapi32/service.c +++ b/rostests/winetests/advapi32/service.c @@ -1323,11 +1323,16 @@ static void test_enum_svc(void) } HeapFree(GetProcessHeap(), 0, services); +#if 0 + /* These tests don't make sense on a real system because no test can determine + * how many service should be active or inactive. + */ todo_wine { ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive); ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive); } +#endif CloseServiceHandle(scm_handle); @@ -1681,8 +1686,13 @@ static void test_enum_svc(void) } HeapFree(GetProcessHeap(), 0, exservices); +#if 0 + /* These tests don't make sense on a real system because no test can determine + * how many service should be active or inactive. + */ ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive); ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive); +#endif CloseServiceHandle(scm_handle); } From 164140d9046a35b7c5892aa1519b8f3a2467d51b Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Sat, 26 Mar 2011 21:41:49 +0000 Subject: [PATCH 90/90] Fix duplicated startup version string Patch by Thomas Faber See issue #6015 for more details. svn path=/trunk/; revision=51165 --- reactos/ntoskrnl/ex/init.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index f614cf659e2..302d1fff48a 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -1410,10 +1410,13 @@ Phase1InitializationDiscard(IN PVOID Context) else { /* No version */ - *EndBuffer++ = ANSI_NULL; /* Null-terminate the string */ - --Remaining; + *EndBuffer = ANSI_NULL; /* Null-terminate the string */ } + /* Skip over the null-terminator to start a new string */ + ++EndBuffer; + --Remaining; + /* Build the version number */ StringBuffer = InitBuffer->VersionNumber; Status = RtlStringCbPrintfA(StringBuffer,