diff --git a/base/applications/network/net/CMakeLists.txt b/base/applications/network/net/CMakeLists.txt index c3507d6627e..5ae08e7a185 100644 --- a/base/applications/network/net/CMakeLists.txt +++ b/base/applications/network/net/CMakeLists.txt @@ -10,6 +10,7 @@ list(APPEND SOURCE cmdPause.c cmdStart.c cmdStop.c + cmdUser.c help.c net.h) diff --git a/base/applications/network/net/cmdUser.c b/base/applications/network/net/cmdUser.c new file mode 100644 index 00000000000..a8289ea80bc --- /dev/null +++ b/base/applications/network/net/cmdUser.c @@ -0,0 +1,348 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS net command + * FILE: + * PURPOSE: + * + * PROGRAMMERS: Eric Kohl + */ + +#include "net.h" + + +static +int +CompareInfo(const void *a, + const void *b) +{ + return _wcsicmp(((PUSER_INFO_0)a)->usri0_name, + ((PUSER_INFO_0)b)->usri0_name); +} + + +static +NET_API_STATUS +EnumerateUsers(VOID) +{ + PUSER_INFO_0 pBuffer = NULL; + PSERVER_INFO_100 pServer = NULL; + DWORD dwRead = 0, dwTotal = 0; + DWORD i; + DWORD_PTR ResumeHandle = 0; + NET_API_STATUS Status; + + Status = NetServerGetInfo(NULL, + 100, + (LPBYTE*)&pServer); + if (Status != NERR_Success) + return Status; + + printf("\nUser accounts for \\\\%S\n\n", pServer->sv100_name); + + NetApiBufferFree(pServer); + + printf("------------------------------------------\n"); + + Status = NetUserEnum(NULL, + 0, + 0, + (LPBYTE*)&pBuffer, + MAX_PREFERRED_LENGTH, + &dwRead, + &dwTotal, + &ResumeHandle); + if (Status != NERR_Success) + return Status; + + qsort(pBuffer, + dwRead, + sizeof(PUSER_INFO_0), + CompareInfo); + +// printf("dwRead: %lu dwTotal: %lu\n", dwRead, dwTotal); + for (i = 0; i < dwRead; i++) + { +// printf("%p\n", pBuffer[i].lgrpi0_name); + if (pBuffer[i].usri0_name) + printf("%S\n", pBuffer[i].usri0_name); + } + + NetApiBufferFree(pBuffer); + + return NERR_Success; +} + + +static +VOID +PrintDateTime(DWORD dwSeconds) +{ + LARGE_INTEGER Time; + FILETIME FileTime; + SYSTEMTIME SystemTime; + WCHAR DateBuffer[80]; + WCHAR TimeBuffer[80]; + + RtlSecondsSince1970ToTime(dwSeconds, &Time); + FileTime.dwLowDateTime = Time.u.LowPart; + FileTime.dwHighDateTime = Time.u.HighPart; + FileTimeToSystemTime(&FileTime, &SystemTime); + + GetDateFormatW(LOCALE_USER_DEFAULT, + DATE_SHORTDATE, + &SystemTime, + NULL, + DateBuffer, + 80); + + GetTimeFormatW(LOCALE_USER_DEFAULT, + TIME_NOSECONDS, + &SystemTime, + NULL, + TimeBuffer, + 80); + + printf("%S %S\n", DateBuffer, TimeBuffer); +} + + +static +NET_API_STATUS +DisplayUser(LPWSTR lpUserName) +{ + PUSER_INFO_4 pUserInfo = NULL; + NET_API_STATUS Status; + + /* Modify the user */ + Status = NetUserGetInfo(NULL, + lpUserName, + 4, + (LPBYTE*)&pUserInfo); + if (Status != NERR_Success) + return Status; + + printf("User name %S\n", pUserInfo->usri4_name); + printf("Full name %S\n", pUserInfo->usri4_full_name); + printf("Comment %S\n", pUserInfo->usri4_comment); + printf("User comment %S\n", pUserInfo->usri4_usr_comment); + printf("Country code %03ld ()\n", pUserInfo->usri4_country_code); + printf("Account active %S\n", (pUserInfo->usri4_flags & UF_ACCOUNTDISABLE)? L"No" : ((pUserInfo->usri4_flags & UF_LOCKOUT) ? L"Locked" : L"Yes")); + printf("Account expires "); + if (pUserInfo->usri4_acct_expires == TIMEQ_FOREVER) + printf("Never\n"); + else + PrintDateTime(pUserInfo->usri4_acct_expires); + + printf("\n"); + printf("Password last set \n"); + printf("Password expires \n"); + printf("Password changeable \n"); + printf("Password required \n"); + printf("User may change password \n"); + printf("\n"); + printf("Workstation allowed %S\n", pUserInfo->usri4_workstations); + printf("Logon script %S\n", pUserInfo->usri4_script_path); + printf("User profile %S\n", pUserInfo->usri4_profile); + printf("Home directory %S\n", pUserInfo->usri4_home_dir); + printf("Last logon "); + if (pUserInfo->usri4_last_logon == 0) + printf("Never\n"); + else + PrintDateTime(pUserInfo->usri4_last_logon); + printf("\n"); + printf("Logon hours allowed \n"); + printf("\n"); + printf("Local group memberships \n"); + printf("Global group memberships \n"); + + if (pUserInfo != NULL) + NetApiBufferFree(pUserInfo); + + return NERR_Success; +} + + +INT +cmdUser( + INT argc, + WCHAR **argv) +{ + INT i, j; + INT result = 0; + BOOL bAdd = FALSE; + BOOL bDelete = FALSE; +#if 0 + BOOL bDomain = FALSE; +#endif + LPWSTR lpUserName = NULL; + LPWSTR lpPassword = NULL; + PUSER_INFO_4 pUserInfo = NULL; + USER_INFO_4 UserInfo; + NET_API_STATUS Status; + + if (argc == 2) + { + Status = EnumerateUsers(); + printf("Status: %lu\n", Status); + return 0; + } + else if (argc == 3) + { + Status = DisplayUser(argv[2]); + printf("Status: %lu\n", Status); + return 0; + } + + i = 2; + if (argv[i][0] != L'/') + { + lpUserName = argv[i]; + printf("User: %S\n", lpUserName); + i++; + } + + if (argv[i][0] != L'/') + { + lpPassword = argv[i]; + printf("Password: %S\n", lpPassword); + i++; + } + + for (j = i; j < argc; j++) + { + if (_wcsicmp(argv[j], L"/help") == 0) + { + PrintResourceString(IDS_USER_HELP); + return 0; + } + else if (_wcsicmp(argv[j], L"/add") == 0) + { + bAdd = TRUE; + } + else if (_wcsicmp(argv[j], L"/delete") == 0) + { + bDelete = TRUE; + } + else if (_wcsicmp(argv[j], L"/domain") == 0) + { + printf("The /DOMAIN option is not supported yet!\n"); +#if 0 + bDomain = TRUE; +#endif + } + } + + if (bAdd && bDelete) + { + result = 1; + goto done; + } + + if (!bAdd && !bDelete) + { + /* Modify the user */ + Status = NetUserGetInfo(NULL, + lpUserName, + 4, + (LPBYTE*)&pUserInfo); + printf("Status: %lu\n", Status); + } + else if (bAdd && !bDelete) + { + /* Add the user */ + ZeroMemory(&UserInfo, sizeof(USER_INFO_4)); + + UserInfo.usri4_name = lpUserName; + UserInfo.usri4_password = lpPassword; + UserInfo.usri4_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT; + + pUserInfo = &UserInfo; + } + + for (j = i; j < argc; j++) + { + if (_wcsnicmp(argv[j], L"/active:", 8) == 0) + { + } + else if (_wcsnicmp(argv[j], L"/comment:", 9) == 0) + { + pUserInfo->usri4_comment = &argv[j][9]; + } + else if (_wcsnicmp(argv[j], L"/countrycode:", 13) == 0) + { + } + else if (_wcsnicmp(argv[j], L"/expires:", 9) == 0) + { + } + else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0) + { + pUserInfo->usri4_full_name = &argv[j][10]; + } + else if (_wcsnicmp(argv[j], L"/homedir:", 9) == 0) + { + pUserInfo->usri4_home_dir = &argv[j][9]; + } + else if (_wcsnicmp(argv[j], L"/passwordchg:", 13) == 0) + { + } + else if (_wcsnicmp(argv[j], L"/passwordreq:", 13) == 0) + { + } + else if (_wcsnicmp(argv[j], L"/profilepath:", 13) == 0) + { + pUserInfo->usri4_profile = &argv[j][13]; + } + else if (_wcsnicmp(argv[j], L"/scriptpath:", 12) == 0) + { + pUserInfo->usri4_script_path = &argv[j][12]; + } + else if (_wcsnicmp(argv[j], L"/times:", 7) == 0) + { + } + else if (_wcsnicmp(argv[j], L"/usercomment:", 13) == 0) + { + pUserInfo->usri4_usr_comment = &argv[j][13]; + } + else if (_wcsnicmp(argv[j], L"/workstations:", 14) == 0) + { + } + } + + if (!bAdd && !bDelete) + { + /* Modify the user */ + Status = NetUserSetInfo(NULL, + lpUserName, + 4, + (LPBYTE)pUserInfo, + NULL); + printf("Status: %lu\n", Status); + } + else if (bAdd && !bDelete) + { + /* Add the user */ + Status = NetUserAdd(NULL, + 4, + (LPBYTE)pUserInfo, + NULL); + printf("Status: %lu\n", Status); + } + else if (!bAdd && bDelete) + { + /* Delete the user */ + Status = NetUserDel(NULL, + lpUserName); + printf("Status: %lu\n", Status); + } + +done: + if (!bAdd && !bDelete && pUserInfo != NULL) + NetApiBufferFree(pUserInfo); + + if (result != 0) + PrintResourceString(IDS_USER_SYNTAX); + + return result; +} + +/* EOF */ diff --git a/base/applications/network/net/lang/en-US.rc b/base/applications/network/net/lang/en-US.rc index 2d9083e1445..d84ca737a50 100644 --- a/base/applications/network/net/lang/en-US.rc +++ b/base/applications/network/net/lang/en-US.rc @@ -44,7 +44,9 @@ BEGIN IDS_TIME_HELP "TIME\n..." IDS_USE_SYNTAX "Usage:\nNET USE ..." IDS_USE_HELP "USE\n..." - IDS_USER_SYNTAX "Usage:\nNET USER ..." + IDS_USER_SYNTAX "Usage:\nNET USER [username [password | *] [options]] [/DOMAIN]\n\ + username {password | *} /ADD [options] [/DOMAIN]\n\ + username [/DELETE] [/DOMAIN]" IDS_USER_HELP "USER\n..." IDS_VIEW_SYNTAX "Usage:\nNET VIEW ..." IDS_VIEW_HELP "VIEW\n..." diff --git a/base/applications/network/net/lang/ro-RO.rc b/base/applications/network/net/lang/ro-RO.rc index c8641eba1db..6ed299ca7e1 100644 --- a/base/applications/network/net/lang/ro-RO.rc +++ b/base/applications/network/net/lang/ro-RO.rc @@ -50,7 +50,9 @@ BEGIN IDS_TIME_HELP "TIME\n..." IDS_USE_SYNTAX "Utilizare:\nNET USE ..." IDS_USE_HELP "USE\n..." - IDS_USER_SYNTAX "Utilizare:\nNET USER ..." + IDS_USER_SYNTAX "Utilizare:\nNET USER [username [password | *] [options]] [/DOMAIN]\n\ + username {password | *} /ADD [options] [/DOMAIN]\n\ + username [/DELETE] [/DOMAIN]" IDS_USER_HELP "USER\n..." IDS_VIEW_SYNTAX "Utilizare:\nNET VIEW ..." IDS_VIEW_HELP "VIEW\n..." diff --git a/base/applications/network/net/lang/ru-RU.rc b/base/applications/network/net/lang/ru-RU.rc index 63531a83d17..076ae07e51f 100644 --- a/base/applications/network/net/lang/ru-RU.rc +++ b/base/applications/network/net/lang/ru-RU.rc @@ -45,7 +45,9 @@ BEGIN IDS_TIME_HELP "TIME\n..." IDS_USE_SYNTAX "Использование:\nNET USE ..." IDS_USE_HELP "USE\n..." - IDS_USER_SYNTAX "Использование:\nNET USER ..." + IDS_USER_SYNTAX "Использование:\nNET USER [username [password | *] [options]] [/DOMAIN]\n\ + username {password | *} /ADD [options] [/DOMAIN]\n\ + username [/DELETE] [/DOMAIN]" IDS_USER_HELP "USER\n..." IDS_VIEW_SYNTAX "Использование:\nNET VIEW ..." IDS_VIEW_HELP "VIEW\n..." diff --git a/base/applications/network/net/main.c b/base/applications/network/net/main.c index 9f226beb2e1..cc93fea82fd 100644 --- a/base/applications/network/net/main.c +++ b/base/applications/network/net/main.c @@ -40,7 +40,7 @@ COMMAND cmds[] = {L"stop", cmdStop}, {L"time", unimplemented}, {L"use", unimplemented}, - {L"user", unimplemented}, + {L"user", cmdUser}, {L"view", unimplemented}, {NULL, NULL} }; diff --git a/base/applications/network/net/net.h b/base/applications/network/net/net.h index 016c018bdf5..e100dc9e84a 100644 --- a/base/applications/network/net/net.h +++ b/base/applications/network/net/net.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -39,5 +40,6 @@ INT cmdLocalGroup(INT argc, WCHAR **argv); INT cmdPause(INT argc, WCHAR **argv); INT cmdStart(INT argc, WCHAR **argv); INT cmdStop(INT argc, WCHAR **argv); +INT cmdUser(INT argc, WCHAR **argv); #endif /* _NET_PCH_ */ diff --git a/dll/directx/wine/dsound/sound3d.c b/dll/directx/wine/dsound/sound3d.c index d5ea87f5598..d95447a7f06 100644 --- a/dll/directx/wine/dsound/sound3d.c +++ b/dll/directx/wine/dsound/sound3d.c @@ -121,6 +121,7 @@ static inline D3DVECTOR VectorBetweenTwoPoints (const D3DVECTOR *a, const D3DVEC return c; } +#ifndef __REACTOS__ /* calculates the length of vector's projection on another vector */ static inline D3DVALUE ProjectVector (const D3DVECTOR *a, const D3DVECTOR *p) { @@ -131,6 +132,7 @@ static inline D3DVALUE ProjectVector (const D3DVECTOR *a, const D3DVECTOR *p) p->y, p->z, result); return result; } +#endif /******************************************************************************* * 3D Buffer and Listener mixing diff --git a/dll/win32/advapi32/CMakeLists.txt b/dll/win32/advapi32/CMakeLists.txt index 484f9234914..fe6bf4647de 100644 --- a/dll/win32/advapi32/CMakeLists.txt +++ b/dll/win32/advapi32/CMakeLists.txt @@ -17,9 +17,6 @@ add_rpc_files(client ${REACTOS_SOURCE_DIR}/include/reactos/idl/svcctl.idl) list(APPEND SOURCE - crypt/crypt.c - crypt/crypt_des.c - crypt/crypt_lmhash.c misc/dllmain.c misc/efs.c misc/hwprofiles.c @@ -44,6 +41,9 @@ list(APPEND SOURCE service/sctrl.c token/privilege.c token/token.c + wine/crypt.c + wine/crypt_des.c + wine/crypt_lmhash.c advapi32.h) add_library(advapi32 SHARED diff --git a/dll/win32/advapi32/advapi32.h b/dll/win32/advapi32/advapi32.h index 41e40f7c255..ce8af8c0890 100644 --- a/dll/win32/advapi32/advapi32.h +++ b/dll/win32/advapi32/advapi32.h @@ -39,7 +39,7 @@ #include #include -#include "crypt/crypt.h" +#include "wine/crypt.h" #ifndef HAS_FN_PROGRESSW #define FN_PROGRESSW FN_PROGRESS diff --git a/dll/win32/advapi32/crypt/crypt.c b/dll/win32/advapi32/wine/crypt.c similarity index 100% rename from dll/win32/advapi32/crypt/crypt.c rename to dll/win32/advapi32/wine/crypt.c diff --git a/dll/win32/advapi32/crypt/crypt.h b/dll/win32/advapi32/wine/crypt.h similarity index 100% rename from dll/win32/advapi32/crypt/crypt.h rename to dll/win32/advapi32/wine/crypt.h diff --git a/dll/win32/advapi32/crypt/crypt_des.c b/dll/win32/advapi32/wine/crypt_des.c similarity index 100% rename from dll/win32/advapi32/crypt/crypt_des.c rename to dll/win32/advapi32/wine/crypt_des.c diff --git a/dll/win32/advapi32/crypt/crypt_lmhash.c b/dll/win32/advapi32/wine/crypt_lmhash.c similarity index 100% rename from dll/win32/advapi32/crypt/crypt_lmhash.c rename to dll/win32/advapi32/wine/crypt_lmhash.c diff --git a/dll/win32/advapi32/crypt/ros_diff.patch b/dll/win32/advapi32/wine/ros_diff.patch similarity index 100% rename from dll/win32/advapi32/crypt/ros_diff.patch rename to dll/win32/advapi32/wine/ros_diff.patch diff --git a/dll/win32/winspool/info.c b/dll/win32/winspool/info.c index 55b5c23d249..c12f162ce9d 100644 --- a/dll/win32/winspool/info.c +++ b/dll/win32/winspool/info.c @@ -28,10 +28,6 @@ #include #include -#include - -WINE_DEFAULT_DEBUG_CHANNEL(winspool); - /****************************************************************************** * GetDefaultPrinterA (WINSPOOL.@) */ diff --git a/drivers/bus/acpi/compbatt/comppnp.c b/drivers/bus/acpi/compbatt/comppnp.c index 5966cda4826..9b430b8ee18 100644 --- a/drivers/bus/acpi/compbatt/comppnp.c +++ b/drivers/bus/acpi/compbatt/comppnp.c @@ -69,7 +69,7 @@ RemoveBatteryFromList(IN PCUNICODE_STRING BatteryName, /* Done */ ExReleaseFastMutex(&DeviceExtension->Lock); if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING RemoveBatteryFromList\n"); - return STATUS_SUCCESS; + return NULL; } BOOLEAN diff --git a/drivers/bus/pcix/pci/id.c b/drivers/bus/pcix/pci/id.c index 1a90a660b18..ec03fdf1356 100644 --- a/drivers/bus/pcix/pci/id.c +++ b/drivers/bus/pcix/pci/id.c @@ -118,7 +118,7 @@ PciInitIdBuffer(IN PPCI_ID_BUFFER IdBuffer) } ULONG -NTAPI +__cdecl PciIdPrintf(IN PPCI_ID_BUFFER IdBuffer, IN PCCH Format, ...) @@ -153,7 +153,7 @@ PciIdPrintf(IN PPCI_ID_BUFFER IdBuffer, } ULONG -NTAPI +__cdecl PciIdPrintfAppend(IN PPCI_ID_BUFFER IdBuffer, IN PCCH Format, ...) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index ac419a318bb..14c16741d8d 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -256,9 +256,11 @@ check Wine current souces first as it may already be fixed. reactos/lib/3rdparty/strmbase # Synced to Wine-1.7.27 advapi32 - - reactos/dll/win32/advapi32/crypt/*.c # Synced to Wine-1.7.27 - reactos/dll/win32/advapi32/sec/cred.c # Synced to Wine-1.7.27 - reactos/dll/win32/advapi32/sec/sid.c # Out of Sync + reactos/dll/win32/advapi32/wine/crypt.c # Synced to Wine-1.7.27 + reactos/dll/win32/advapi32/wine/crypt_des.c # Synced to Wine-1.7.27 + reactos/dll/win32/advapi32/wine/crypt_lmhash.c # Synced to Wine-1.7.27 + reactos/dll/win32/advapi32/sec/cred.c # Synced to Wine-1.7.27 + reactos/dll/win32/advapi32/sec/sid.c # Out of Sync gdi32 - reactos/dll/win32/gdi32/objects/linedda.c # Synced at 20090410 diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index dcf1e6117bb..b6901db8452 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -385,7 +385,7 @@ typedef struct _OPEN_PACKET typedef struct _LOAD_UNLOAD_PARAMS { NTSTATUS Status; - PUNICODE_STRING ServiceName; + PCUNICODE_STRING RegistryPath; WORK_QUEUE_ITEM WorkItem; KEVENT Event; PDRIVER_OBJECT DriverObject; @@ -1083,10 +1083,11 @@ IopLoadServiceModule( OUT PLDR_DATA_TABLE_ENTRY *ModuleObject ); -VOID +NTSTATUS NTAPI IopLoadUnloadDriver( - IN OUT PLOAD_UNLOAD_PARAMS LoadParams + _In_opt_ PCUNICODE_STRING RegistryPath, + _Inout_ PDRIVER_OBJECT *DriverObject ); NTSTATUS diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c index e0e3bb970f8..fbe571b44f9 100644 --- a/ntoskrnl/io/iomgr/driver.c +++ b/ntoskrnl/io/iomgr/driver.c @@ -39,15 +39,16 @@ PLIST_ENTRY IopGroupTable; /* PRIVATE FUNCTIONS **********************************************************/ -NTSTATUS NTAPI +NTSTATUS +NTAPI IopInvalidDeviceRequest( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) + PDEVICE_OBJECT DeviceObject, + PIRP Irp) { - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INVALID_DEVICE_REQUEST; } VOID @@ -64,8 +65,7 @@ IopDeleteDriver(IN PVOID ObjectBody) ASSERT(!DriverObject->DeviceObject); /* Get the extension and loop them */ - DriverExtension = IoGetDrvObjExtension(DriverObject)-> - ClientDriverExtension; + DriverExtension = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension; while (DriverExtension) { /* Get the next one */ @@ -98,61 +98,60 @@ IopDeleteDriver(IN PVOID ObjectBody) } } -NTSTATUS FASTCALL +NTSTATUS +FASTCALL IopGetDriverObject( - PDRIVER_OBJECT *DriverObject, - PUNICODE_STRING ServiceName, - BOOLEAN FileSystem) + PDRIVER_OBJECT *DriverObject, + PUNICODE_STRING ServiceName, + BOOLEAN FileSystem) { - PDRIVER_OBJECT Object; - WCHAR NameBuffer[MAX_PATH]; - UNICODE_STRING DriverName; - NTSTATUS Status; + PDRIVER_OBJECT Object; + WCHAR NameBuffer[MAX_PATH]; + UNICODE_STRING DriverName; + NTSTATUS Status; - DPRINT("IopGetDriverObject(%p '%wZ' %x)\n", - DriverObject, ServiceName, FileSystem); + DPRINT("IopGetDriverObject(%p '%wZ' %x)\n", + DriverObject, ServiceName, FileSystem); - *DriverObject = NULL; + *DriverObject = NULL; - /* Create ModuleName string */ - if (ServiceName == NULL || ServiceName->Buffer == NULL) - /* We don't know which DriverObject we have to open */ - return STATUS_INVALID_PARAMETER_2; + /* Create ModuleName string */ + if (ServiceName == NULL || ServiceName->Buffer == NULL) + /* We don't know which DriverObject we have to open */ + return STATUS_INVALID_PARAMETER_2; - DriverName.Buffer = NameBuffer; - DriverName.Length = 0; - DriverName.MaximumLength = sizeof(NameBuffer); + DriverName.Buffer = NameBuffer; + DriverName.Length = 0; + DriverName.MaximumLength = sizeof(NameBuffer); - if (FileSystem == TRUE) - RtlAppendUnicodeToString(&DriverName, FILESYSTEM_ROOT_NAME); - else - RtlAppendUnicodeToString(&DriverName, DRIVER_ROOT_NAME); - RtlAppendUnicodeStringToString(&DriverName, ServiceName); + if (FileSystem == TRUE) + RtlAppendUnicodeToString(&DriverName, FILESYSTEM_ROOT_NAME); + else + RtlAppendUnicodeToString(&DriverName, DRIVER_ROOT_NAME); + RtlAppendUnicodeStringToString(&DriverName, ServiceName); - DPRINT("Driver name: '%wZ'\n", &DriverName); + DPRINT("Driver name: '%wZ'\n", &DriverName); - /* Open driver object */ - Status = ObReferenceObjectByName( - &DriverName, - OBJ_OPENIF | OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, /* Attributes */ - NULL, /* PassedAccessState */ - 0, /* DesiredAccess */ - IoDriverObjectType, - KernelMode, - NULL, /* ParseContext */ - (PVOID*)&Object); + /* Open driver object */ + Status = ObReferenceObjectByName(&DriverName, + OBJ_OPENIF | OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, /* Attributes */ + NULL, /* PassedAccessState */ + 0, /* DesiredAccess */ + IoDriverObjectType, + KernelMode, + NULL, /* ParseContext */ + (PVOID*)&Object); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to reference driver object, status=0x%08x\n", Status); + return Status; + } - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed to reference driver object, status=0x%08x\n", Status); - return Status; - } + *DriverObject = Object; - *DriverObject = Object; + DPRINT("Driver Object: %p\n", Object); - DPRINT("Driver Object: %p\n", Object); - - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /* @@ -193,7 +192,6 @@ IopSuffixUnicodeString( * * Display 'Loading XXX...' message. */ - VOID FASTCALL INIT_FUNCTION @@ -234,55 +232,55 @@ IopDisplayLoadingMessage(PUNICODE_STRING ServiceName) * Remarks * The input image path isn't freed on error. */ - NTSTATUS FASTCALL IopNormalizeImagePath( - _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) - PUNICODE_STRING ImagePath, - _In_ PUNICODE_STRING ServiceName) + _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) + PUNICODE_STRING ImagePath, + _In_ PUNICODE_STRING ServiceName) { - UNICODE_STRING InputImagePath; + UNICODE_STRING InputImagePath; - DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName); + DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName); - RtlCopyMemory( - &InputImagePath, - ImagePath, - sizeof(UNICODE_STRING)); + RtlCopyMemory(&InputImagePath, + ImagePath, + sizeof(UNICODE_STRING)); - if (InputImagePath.Length == 0) - { - ImagePath->Length = 0; - ImagePath->MaximumLength = - (33 * sizeof(WCHAR)) + ServiceName->Length + sizeof(UNICODE_NULL); - ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength); - if (ImagePath->Buffer == NULL) - return STATUS_NO_MEMORY; + if (InputImagePath.Length == 0) + { + ImagePath->Length = 0; + ImagePath->MaximumLength = + (33 * sizeof(WCHAR)) + ServiceName->Length + sizeof(UNICODE_NULL); + ImagePath->Buffer = ExAllocatePool(NonPagedPool, + ImagePath->MaximumLength); + if (ImagePath->Buffer == NULL) + return STATUS_NO_MEMORY; - RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\system32\\drivers\\"); - RtlAppendUnicodeStringToString(ImagePath, ServiceName); - RtlAppendUnicodeToString(ImagePath, L".sys"); - } else - if (InputImagePath.Buffer[0] != L'\\') - { - ImagePath->Length = 0; - ImagePath->MaximumLength = - 12 * sizeof(WCHAR) + InputImagePath.Length + sizeof(UNICODE_NULL); - ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength); - if (ImagePath->Buffer == NULL) - return STATUS_NO_MEMORY; + RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\system32\\drivers\\"); + RtlAppendUnicodeStringToString(ImagePath, ServiceName); + RtlAppendUnicodeToString(ImagePath, L".sys"); + } + else if (InputImagePath.Buffer[0] != L'\\') + { + ImagePath->Length = 0; + ImagePath->MaximumLength = + 12 * sizeof(WCHAR) + InputImagePath.Length + sizeof(UNICODE_NULL); + ImagePath->Buffer = ExAllocatePool(NonPagedPool, + ImagePath->MaximumLength); + if (ImagePath->Buffer == NULL) + return STATUS_NO_MEMORY; - RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\"); - RtlAppendUnicodeStringToString(ImagePath, &InputImagePath); + RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\"); + RtlAppendUnicodeStringToString(ImagePath, &InputImagePath); - /* Free caller's string */ - ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY); - } + /* Free caller's string */ + ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY); + } - DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName); + DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /* @@ -297,130 +295,129 @@ IopNormalizeImagePath( * Return Value * Status */ - -NTSTATUS FASTCALL +NTSTATUS +FASTCALL IopLoadServiceModule( - IN PUNICODE_STRING ServiceName, - OUT PLDR_DATA_TABLE_ENTRY *ModuleObject) + IN PUNICODE_STRING ServiceName, + OUT PLDR_DATA_TABLE_ENTRY *ModuleObject) { - RTL_QUERY_REGISTRY_TABLE QueryTable[3]; - ULONG ServiceStart; - UNICODE_STRING ServiceImagePath, CCSName; - NTSTATUS Status; - HANDLE CCSKey, ServiceKey; - PVOID BaseAddress; + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; + ULONG ServiceStart; + UNICODE_STRING ServiceImagePath, CCSName; + NTSTATUS Status; + HANDLE CCSKey, ServiceKey; + PVOID BaseAddress; ASSERT(ServiceName->Length); DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject); - if (ExpInTextModeSetup) - { - /* We have no registry, but luckily we know where all the drivers are */ + if (ExpInTextModeSetup) + { + /* We have no registry, but luckily we know where all the drivers are */ - /* ServiceStart < 4 is all that matters */ - ServiceStart = 0; + /* ServiceStart < 4 is all that matters */ + ServiceStart = 0; - /* IopNormalizeImagePath will do all of the work for us if we give it an empty string */ - ServiceImagePath.Length = ServiceImagePath.MaximumLength = 0; - ServiceImagePath.Buffer = NULL; - } - else - { - /* Open CurrentControlSet */ - RtlInitUnicodeString(&CCSName, - L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"); - Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with Status %08X\n", - &CCSName, Status); - return Status; - } + /* IopNormalizeImagePath will do all of the work for us if we give it an empty string */ + ServiceImagePath.Length = ServiceImagePath.MaximumLength = 0; + ServiceImagePath.Buffer = NULL; + } + else + { + /* Open CurrentControlSet */ + RtlInitUnicodeString(&CCSName, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"); + Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with Status %08X\n", + &CCSName, Status); + return Status; + } - /* Open service key */ - Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with Status %08X\n", - ServiceName, Status); - ZwClose(CCSKey); - return Status; - } + /* Open service key */ + Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with Status %08X\n", + ServiceName, Status); + ZwClose(CCSKey); + return Status; + } - /* - * Get information about the service. - */ + /* + * Get information about the service. + */ + RtlZeroMemory(QueryTable, sizeof(QueryTable)); - RtlZeroMemory(QueryTable, sizeof(QueryTable)); + RtlInitUnicodeString(&ServiceImagePath, NULL); - RtlInitUnicodeString(&ServiceImagePath, NULL); + QueryTable[0].Name = L"Start"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].EntryContext = &ServiceStart; - QueryTable[0].Name = L"Start"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].EntryContext = &ServiceStart; + QueryTable[1].Name = L"ImagePath"; + QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[1].EntryContext = &ServiceImagePath; - QueryTable[1].Name = L"ImagePath"; - QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[1].EntryContext = &ServiceImagePath; + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, + (PWSTR)ServiceKey, + QueryTable, + NULL, + NULL); - Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, - (PWSTR)ServiceKey, QueryTable, NULL, NULL); + ZwClose(ServiceKey); + ZwClose(CCSKey); - ZwClose(ServiceKey); - ZwClose(CCSKey); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status); + return Status; + } + } - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status); - return Status; - } - } + /* + * Normalize the image path for all later processing. + */ + Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName); - /* - * Normalize the image path for all later processing. - */ + if (!NT_SUCCESS(Status)) + { + DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status); + return Status; + } - Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName); + /* + * Case for disabled drivers + */ + if (ServiceStart >= 4) + { + /* We can't load this */ + Status = STATUS_DRIVER_UNABLE_TO_LOAD; + } + else + { + DPRINT("Loading module from %wZ\n", &ServiceImagePath); + Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress); + if (NT_SUCCESS(Status)) + { + IopDisplayLoadingMessage(ServiceName); + } + } - if (!NT_SUCCESS(Status)) - { - DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status); - return Status; - } + ExFreePool(ServiceImagePath.Buffer); - /* - * Case for disabled drivers - */ + /* + * Now check if the module was loaded successfully. + */ + if (!NT_SUCCESS(Status)) + { + DPRINT("Module loading failed (Status %x)\n", Status); + } - if (ServiceStart >= 4) - { - /* We can't load this */ - Status = STATUS_DRIVER_UNABLE_TO_LOAD; - } - else - { - DPRINT("Loading module from %wZ\n", &ServiceImagePath); - Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress); - if (NT_SUCCESS(Status)) - { - IopDisplayLoadingMessage(ServiceName); - } - } + DPRINT("Module loading (Status %x)\n", Status); - ExFreePool(ServiceImagePath.Buffer); - - /* - * Now check if the module was loaded successfully. - */ - - if (!NT_SUCCESS(Status)) - { - DPRINT("Module loading failed (Status %x)\n", Status); - } - - DPRINT("Module loading (Status %x)\n", Status); - - return Status; + return Status; } VOID @@ -450,84 +447,83 @@ MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry); * On successful return this contains the driver object representing * the loaded driver. */ - -NTSTATUS FASTCALL +NTSTATUS +FASTCALL IopInitializeDriverModule( - IN PDEVICE_NODE DeviceNode, - IN PLDR_DATA_TABLE_ENTRY ModuleObject, - IN PUNICODE_STRING ServiceName, - IN BOOLEAN FileSystemDriver, - OUT PDRIVER_OBJECT *DriverObject) + IN PDEVICE_NODE DeviceNode, + IN PLDR_DATA_TABLE_ENTRY ModuleObject, + IN PUNICODE_STRING ServiceName, + IN BOOLEAN FileSystemDriver, + OUT PDRIVER_OBJECT *DriverObject) { - const WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"; - WCHAR NameBuffer[MAX_PATH]; - UNICODE_STRING DriverName; - UNICODE_STRING RegistryKey; - PDRIVER_INITIALIZE DriverEntry; - PDRIVER_OBJECT Driver; - NTSTATUS Status; + const WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"; + WCHAR NameBuffer[MAX_PATH]; + UNICODE_STRING DriverName; + UNICODE_STRING RegistryKey; + PDRIVER_INITIALIZE DriverEntry; + PDRIVER_OBJECT Driver; + NTSTATUS Status; - DriverEntry = ModuleObject->EntryPoint; + DriverEntry = ModuleObject->EntryPoint; - if (ServiceName != NULL && ServiceName->Length != 0) - { - RegistryKey.Length = 0; - RegistryKey.MaximumLength = sizeof(ServicesKeyName) + ServiceName->Length; - RegistryKey.Buffer = ExAllocatePool(PagedPool, RegistryKey.MaximumLength); - if (RegistryKey.Buffer == NULL) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - RtlAppendUnicodeToString(&RegistryKey, ServicesKeyName); - RtlAppendUnicodeStringToString(&RegistryKey, ServiceName); - } - else - { - RtlInitUnicodeString(&RegistryKey, NULL); - } + if (ServiceName != NULL && ServiceName->Length != 0) + { + RegistryKey.Length = 0; + RegistryKey.MaximumLength = sizeof(ServicesKeyName) + ServiceName->Length; + RegistryKey.Buffer = ExAllocatePool(PagedPool, RegistryKey.MaximumLength); + if (RegistryKey.Buffer == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + RtlAppendUnicodeToString(&RegistryKey, ServicesKeyName); + RtlAppendUnicodeStringToString(&RegistryKey, ServiceName); + } + else + { + RtlInitUnicodeString(&RegistryKey, NULL); + } - /* Create ModuleName string */ - if (ServiceName && ServiceName->Length > 0) - { - if (FileSystemDriver == TRUE) - wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME); - else - wcscpy(NameBuffer, DRIVER_ROOT_NAME); + /* Create ModuleName string */ + if (ServiceName && ServiceName->Length > 0) + { + if (FileSystemDriver == TRUE) + wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME); + else + wcscpy(NameBuffer, DRIVER_ROOT_NAME); - RtlInitUnicodeString(&DriverName, NameBuffer); - DriverName.MaximumLength = sizeof(NameBuffer); + RtlInitUnicodeString(&DriverName, NameBuffer); + DriverName.MaximumLength = sizeof(NameBuffer); - RtlAppendUnicodeStringToString(&DriverName, ServiceName); + RtlAppendUnicodeStringToString(&DriverName, ServiceName); - DPRINT("Driver name: '%wZ'\n", &DriverName); - } - else - DriverName.Length = 0; + DPRINT("Driver name: '%wZ'\n", &DriverName); + } + else + DriverName.Length = 0; - Status = IopCreateDriver( - DriverName.Length > 0 ? &DriverName : NULL, - DriverEntry, - &RegistryKey, - ServiceName, - ModuleObject, - &Driver); - RtlFreeUnicodeString(&RegistryKey); + Status = IopCreateDriver(DriverName.Length > 0 ? &DriverName : NULL, + DriverEntry, + &RegistryKey, + ServiceName, + ModuleObject, + &Driver); + RtlFreeUnicodeString(&RegistryKey); - *DriverObject = Driver; - if (!NT_SUCCESS(Status)) - { - DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status); - return Status; - } + *DriverObject = Driver; + if (!NT_SUCCESS(Status)) + { + DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status); + return Status; + } - MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)Driver->DriverSection); + MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)Driver->DriverSection); - /* Set the driver as initialized */ - IopReadyDeviceObjects(Driver); + /* Set the driver as initialized */ + IopReadyDeviceObjects(Driver); - if (PnpSystemInit) IopReinitializeDrivers(); + if (PnpSystemInit) IopReinitializeDrivers(); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /* @@ -535,64 +531,67 @@ IopInitializeDriverModule( * * Internal routine used by IopAttachFilterDrivers. */ - -NTSTATUS NTAPI +NTSTATUS +NTAPI IopAttachFilterDriversCallback( - PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext) + PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) { - PDEVICE_NODE DeviceNode = Context; - UNICODE_STRING ServiceName; - PWCHAR Filters; - PLDR_DATA_TABLE_ENTRY ModuleObject; - PDRIVER_OBJECT DriverObject; - NTSTATUS Status; + PDEVICE_NODE DeviceNode = Context; + UNICODE_STRING ServiceName; + PWCHAR Filters; + PLDR_DATA_TABLE_ENTRY ModuleObject; + PDRIVER_OBJECT DriverObject; + NTSTATUS Status; - /* No filter value present */ - if (ValueType == REG_NONE) - return STATUS_SUCCESS; + /* No filter value present */ + if (ValueType == REG_NONE) + return STATUS_SUCCESS; - for (Filters = ValueData; - ((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength && - *Filters != 0; - Filters += (ServiceName.Length / sizeof(WCHAR)) + 1) - { - DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath); + for (Filters = ValueData; + ((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength && + *Filters != 0; + Filters += (ServiceName.Length / sizeof(WCHAR)) + 1) + { + DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath); - ServiceName.Buffer = Filters; - ServiceName.MaximumLength = - ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR); + ServiceName.Buffer = Filters; + ServiceName.MaximumLength = + ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR); - Status = IopGetDriverObject(&DriverObject, - &ServiceName, - FALSE); - if (!NT_SUCCESS(Status)) - { - /* Load and initialize the filter driver */ - Status = IopLoadServiceModule(&ServiceName, &ModuleObject); - if (!NT_SUCCESS(Status)) - return Status; + Status = IopGetDriverObject(&DriverObject, + &ServiceName, + FALSE); + if (!NT_SUCCESS(Status)) + { + /* Load and initialize the filter driver */ + Status = IopLoadServiceModule(&ServiceName, &ModuleObject); + if (!NT_SUCCESS(Status)) + return Status; - Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName, - FALSE, &DriverObject); - if (!NT_SUCCESS(Status)) - return Status; - } + Status = IopInitializeDriverModule(DeviceNode, + ModuleObject, + &ServiceName, + FALSE, + &DriverObject); + if (!NT_SUCCESS(Status)) + return Status; + } - Status = IopInitializeDevice(DeviceNode, DriverObject); + Status = IopInitializeDevice(DeviceNode, DriverObject); - /* Remove extra reference */ - ObDereferenceObject(DriverObject); + /* Remove extra reference */ + ObDereferenceObject(DriverObject); - if (!NT_SUCCESS(Status)) - return Status; - } + if (!NT_SUCCESS(Status)) + return Status; + } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /* @@ -605,143 +604,148 @@ IopAttachFilterDriversCallback( * Set to TRUE for loading lower level filters or FALSE for upper * level filters. */ - -NTSTATUS FASTCALL +NTSTATUS +FASTCALL IopAttachFilterDrivers( - PDEVICE_NODE DeviceNode, - BOOLEAN Lower) + PDEVICE_NODE DeviceNode, + BOOLEAN Lower) { - RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { NULL, 0, NULL, NULL, 0, NULL, 0 }, }; - UNICODE_STRING Class; - WCHAR ClassBuffer[40]; - UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT); - HANDLE EnumRootKey, SubKey; - NTSTATUS Status; + RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { NULL, 0, NULL, NULL, 0, NULL, 0 }, }; + UNICODE_STRING Class; + WCHAR ClassBuffer[40]; + UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT); + HANDLE EnumRootKey, SubKey; + NTSTATUS Status; - /* Open enumeration root key */ - Status = IopOpenRegistryKeyEx(&EnumRootKey, NULL, - &EnumRoot, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); - return Status; - } + /* Open enumeration root key */ + Status = IopOpenRegistryKeyEx(&EnumRootKey, + NULL, + &EnumRoot, + KEY_READ); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); + return Status; + } - /* Open subkey */ - Status = IopOpenRegistryKeyEx(&SubKey, EnumRootKey, - &DeviceNode->InstancePath, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); - ZwClose(EnumRootKey); - return Status; - } + /* Open subkey */ + Status = IopOpenRegistryKeyEx(&SubKey, + EnumRootKey, + &DeviceNode->InstancePath, + KEY_READ); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); + ZwClose(EnumRootKey); + return Status; + } - /* - * First load the device filters - */ - QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; - if (Lower) - QueryTable[0].Name = L"LowerFilters"; - else - QueryTable[0].Name = L"UpperFilters"; - QueryTable[0].Flags = 0; - QueryTable[0].DefaultType = REG_NONE; + /* + * First load the device filters + */ + QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; + if (Lower) + QueryTable[0].Name = L"LowerFilters"; + else + QueryTable[0].Name = L"UpperFilters"; + QueryTable[0].Flags = 0; + QueryTable[0].DefaultType = REG_NONE; - Status = RtlQueryRegistryValues( - RTL_REGISTRY_HANDLE, - (PWSTR)SubKey, - QueryTable, - DeviceNode, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to load device %s filters: %08X\n", - Lower ? "lower" : "upper", Status); - ZwClose(SubKey); - ZwClose(EnumRootKey); - return Status; - } + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, + (PWSTR)SubKey, + QueryTable, + DeviceNode, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to load device %s filters: %08X\n", + Lower ? "lower" : "upper", Status); + ZwClose(SubKey); + ZwClose(EnumRootKey); + return Status; + } - /* - * Now get the class GUID - */ - Class.Length = 0; - Class.MaximumLength = 40 * sizeof(WCHAR); - Class.Buffer = ClassBuffer; - QueryTable[0].QueryRoutine = NULL; - QueryTable[0].Name = L"ClassGUID"; - QueryTable[0].EntryContext = &Class; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; + /* + * Now get the class GUID + */ + Class.Length = 0; + Class.MaximumLength = 40 * sizeof(WCHAR); + Class.Buffer = ClassBuffer; + QueryTable[0].QueryRoutine = NULL; + QueryTable[0].Name = L"ClassGUID"; + QueryTable[0].EntryContext = &Class; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; - Status = RtlQueryRegistryValues( - RTL_REGISTRY_HANDLE, - (PWSTR)SubKey, - QueryTable, - DeviceNode, - NULL); + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, + (PWSTR)SubKey, + QueryTable, + DeviceNode, + NULL); - /* Close handles */ - ZwClose(SubKey); - ZwClose(EnumRootKey); + /* Close handles */ + ZwClose(SubKey); + ZwClose(EnumRootKey); - /* - * Load the class filter driver - */ - if (NT_SUCCESS(Status)) - { - UNICODE_STRING ControlClass = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class"); + /* + * Load the class filter driver + */ + if (NT_SUCCESS(Status)) + { + UNICODE_STRING ControlClass = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class"); - Status = IopOpenRegistryKeyEx(&EnumRootKey, NULL, - &ControlClass, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); - return Status; - } + Status = IopOpenRegistryKeyEx(&EnumRootKey, + NULL, + &ControlClass, + KEY_READ); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); + return Status; + } - /* Open subkey */ - Status = IopOpenRegistryKeyEx(&SubKey, EnumRootKey, - &Class, KEY_READ); - if (!NT_SUCCESS(Status)) - { - /* It's okay if there's no class key */ - DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); - ZwClose(EnumRootKey); - return STATUS_SUCCESS; - } + /* Open subkey */ + Status = IopOpenRegistryKeyEx(&SubKey, + EnumRootKey, + &Class, + KEY_READ); + if (!NT_SUCCESS(Status)) + { + /* It's okay if there's no class key */ + DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); + ZwClose(EnumRootKey); + return STATUS_SUCCESS; + } - QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; - if (Lower) - QueryTable[0].Name = L"LowerFilters"; - else - QueryTable[0].Name = L"UpperFilters"; - QueryTable[0].EntryContext = NULL; - QueryTable[0].Flags = 0; - QueryTable[0].DefaultType = REG_NONE; + QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; + if (Lower) + QueryTable[0].Name = L"LowerFilters"; + else + QueryTable[0].Name = L"UpperFilters"; + QueryTable[0].EntryContext = NULL; + QueryTable[0].Flags = 0; + QueryTable[0].DefaultType = REG_NONE; - Status = RtlQueryRegistryValues( - RTL_REGISTRY_HANDLE, - (PWSTR)SubKey, - QueryTable, - DeviceNode, - NULL); + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, + (PWSTR)SubKey, + QueryTable, + DeviceNode, + NULL); - /* Clean up */ - ZwClose(SubKey); - ZwClose(EnumRootKey); + /* Clean up */ + ZwClose(SubKey); + ZwClose(EnumRootKey); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to load class %s filters: %08X\n", - Lower ? "lower" : "upper", Status); - ZwClose(SubKey); - ZwClose(EnumRootKey); - return Status; - } - } + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to load class %s filters: %08X\n", + Lower ? "lower" : "upper", Status); + ZwClose(SubKey); + ZwClose(EnumRootKey); + return Status; + } + } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } NTSTATUS @@ -836,7 +840,6 @@ LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry, * * Initialize a driver that is already loaded in memory. */ - NTSTATUS NTAPI INIT_FUNCTION @@ -852,85 +855,91 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry) PLIST_ENTRY NextEntry; UNICODE_STRING ServiceName; - /* - * Display 'Loading XXX...' message - */ - IopDisplayLoadingMessage(ModuleName); - InbvIndicateProgress(); + /* + * Display 'Loading XXX...' message + */ + IopDisplayLoadingMessage(ModuleName); + InbvIndicateProgress(); - /* - * Generate filename without path (not needed by freeldr) - */ - FileNameWithoutPath = wcsrchr(ModuleName->Buffer, L'\\'); - if (FileNameWithoutPath == NULL) - { - FileNameWithoutPath = ModuleName->Buffer; - } - else - { - FileNameWithoutPath++; - } + /* + * Generate filename without path (not needed by freeldr) + */ + FileNameWithoutPath = wcsrchr(ModuleName->Buffer, L'\\'); + if (FileNameWithoutPath == NULL) + { + FileNameWithoutPath = ModuleName->Buffer; + } + else + { + FileNameWithoutPath++; + } - /* - * Strip the file extension from ServiceName - */ - RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath); - FileExtension = wcsrchr(ServiceName.Buffer, '.'); - if (FileExtension != NULL) - { - ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR); - FileExtension[0] = 0; - } + /* + * Strip the file extension from ServiceName + */ + RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath); + FileExtension = wcsrchr(ServiceName.Buffer, '.'); + if (FileExtension != NULL) + { + ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR); + FileExtension[0] = 0; + } - /* - * Determine the right device object - */ - /* Use IopRootDeviceNode for now */ - Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status); - return(Status); - } + /* + * Determine the right device object + */ + /* Use IopRootDeviceNode for now */ + Status = IopCreateDeviceNode(IopRootDeviceNode, + NULL, + &ServiceName, + &DeviceNode); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status); + return(Status); + } - /* Lookup the new Ldr entry in PsLoadedModuleList */ - NextEntry = PsLoadedModuleList.Flink; - while (NextEntry != &PsLoadedModuleList) - { - LdrEntry = CONTAINING_RECORD(NextEntry, - LDR_DATA_TABLE_ENTRY, - InLoadOrderLinks); - if (RtlEqualUnicodeString(ModuleName, &LdrEntry->BaseDllName, TRUE)) - { - break; - } + /* Lookup the new Ldr entry in PsLoadedModuleList */ + NextEntry = PsLoadedModuleList.Flink; + while (NextEntry != &PsLoadedModuleList) + { + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + if (RtlEqualUnicodeString(ModuleName, &LdrEntry->BaseDllName, TRUE)) + { + break; + } - NextEntry = NextEntry->Flink; - } - NT_ASSERT(NextEntry != &PsLoadedModuleList); + NextEntry = NextEntry->Flink; + } + NT_ASSERT(NextEntry != &PsLoadedModuleList); - /* - * Initialize the driver - */ - Status = IopInitializeDriverModule(DeviceNode, LdrEntry, - &DeviceNode->ServiceName, FALSE, &DriverObject); + /* + * Initialize the driver + */ + Status = IopInitializeDriverModule(DeviceNode, + LdrEntry, + &DeviceNode->ServiceName, + FALSE, + &DriverObject); - if (!NT_SUCCESS(Status)) - { - IopFreeDeviceNode(DeviceNode); - return Status; - } + if (!NT_SUCCESS(Status)) + { + IopFreeDeviceNode(DeviceNode); + return Status; + } - Status = IopInitializeDevice(DeviceNode, DriverObject); - if (NT_SUCCESS(Status)) - { - Status = IopStartDevice(DeviceNode); - } + Status = IopInitializeDevice(DeviceNode, DriverObject); + if (NT_SUCCESS(Status)) + { + Status = IopStartDevice(DeviceNode); + } - /* Remove extra reference from IopInitializeDriverModule */ - ObDereferenceObject(DriverObject); + /* Remove extra reference from IopInitializeDriverModule */ + ObDereferenceObject(DriverObject); - return Status; + return Status; } /* @@ -1195,204 +1204,180 @@ IopInitializeSystemDrivers(VOID) NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) { - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - UNICODE_STRING ImagePath; - UNICODE_STRING ServiceName; - UNICODE_STRING ObjectName; - PDRIVER_OBJECT DriverObject; - PDEVICE_OBJECT DeviceObject; - PEXTENDED_DEVOBJ_EXTENSION DeviceExtension; - LOAD_UNLOAD_PARAMS LoadParams; - NTSTATUS Status; - LPWSTR Start; - BOOLEAN SafeToUnload = TRUE; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + UNICODE_STRING ImagePath; + UNICODE_STRING ServiceName; + UNICODE_STRING ObjectName; + PDRIVER_OBJECT DriverObject; + PDEVICE_OBJECT DeviceObject; + PEXTENDED_DEVOBJ_EXTENSION DeviceExtension; + NTSTATUS Status; + LPWSTR Start; + BOOLEAN SafeToUnload = TRUE; - DPRINT("IopUnloadDriver('%wZ', %u)\n", DriverServiceName, UnloadPnpDrivers); + DPRINT("IopUnloadDriver('%wZ', %u)\n", DriverServiceName, UnloadPnpDrivers); - PAGED_CODE(); + PAGED_CODE(); - /* - * Get the service name from the registry key name - */ + /* + * Get the service name from the registry key name + */ - Start = wcsrchr(DriverServiceName->Buffer, L'\\'); - if (Start == NULL) - Start = DriverServiceName->Buffer; - else - Start++; + Start = wcsrchr(DriverServiceName->Buffer, L'\\'); + if (Start == NULL) + Start = DriverServiceName->Buffer; + else + Start++; - RtlInitUnicodeString(&ServiceName, Start); + RtlInitUnicodeString(&ServiceName, Start); - /* - * Construct the driver object name - */ + /* + * Construct the driver object name + */ - ObjectName.Length = ((USHORT)wcslen(Start) + 8) * sizeof(WCHAR); - ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR); - ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength); - if (!ObjectName.Buffer) return STATUS_INSUFFICIENT_RESOURCES; - wcscpy(ObjectName.Buffer, DRIVER_ROOT_NAME); - memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR)); - ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = 0; + ObjectName.Length = ((USHORT)wcslen(Start) + 8) * sizeof(WCHAR); + ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR); + ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength); + if (!ObjectName.Buffer) return STATUS_INSUFFICIENT_RESOURCES; + wcscpy(ObjectName.Buffer, DRIVER_ROOT_NAME); + memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR)); + ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = 0; - /* - * Find the driver object - */ - Status = ObReferenceObjectByName(&ObjectName, - 0, - 0, - 0, - IoDriverObjectType, - KernelMode, - 0, - (PVOID*)&DriverObject); + /* + * Find the driver object + */ + Status = ObReferenceObjectByName(&ObjectName, + 0, + 0, + 0, + IoDriverObjectType, + KernelMode, + 0, + (PVOID*)&DriverObject); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Can't locate driver object for %wZ\n", &ObjectName); - ExFreePool(ObjectName.Buffer); - return Status; - } + if (!NT_SUCCESS(Status)) + { + DPRINT1("Can't locate driver object for %wZ\n", &ObjectName); + ExFreePool(ObjectName.Buffer); + return Status; + } - /* - * Free the buffer for driver object name - */ - ExFreePool(ObjectName.Buffer); + /* + * Free the buffer for driver object name + */ + ExFreePool(ObjectName.Buffer); - /* Check that driver is not already unloading */ - if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) - { - DPRINT1("Driver deletion pending\n"); - ObDereferenceObject(DriverObject); - return STATUS_DELETE_PENDING; - } + /* Check that driver is not already unloading */ + if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) + { + DPRINT1("Driver deletion pending\n"); + ObDereferenceObject(DriverObject); + return STATUS_DELETE_PENDING; + } - /* - * Get path of service... - */ + /* + * Get path of service... + */ + RtlZeroMemory(QueryTable, sizeof(QueryTable)); - RtlZeroMemory(QueryTable, sizeof(QueryTable)); + RtlInitUnicodeString(&ImagePath, NULL); - RtlInitUnicodeString(&ImagePath, NULL); + QueryTable[0].Name = L"ImagePath"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].EntryContext = &ImagePath; - QueryTable[0].Name = L"ImagePath"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].EntryContext = &ImagePath; + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + DriverServiceName->Buffer, + QueryTable, + NULL, + NULL); - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - DriverServiceName->Buffer, QueryTable, NULL, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status); + ObDereferenceObject(DriverObject); + return Status; + } - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status); - ObDereferenceObject(DriverObject); - return Status; - } + /* + * Normalize the image path for all later processing. + */ + Status = IopNormalizeImagePath(&ImagePath, &ServiceName); - /* - * Normalize the image path for all later processing. - */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status); + ObDereferenceObject(DriverObject); + return Status; + } - Status = IopNormalizeImagePath(&ImagePath, &ServiceName); + /* + * Free the service path + */ + ExFreePool(ImagePath.Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status); - ObDereferenceObject(DriverObject); - return Status; - } - - /* - * Free the service path - */ - - ExFreePool(ImagePath.Buffer); - - /* - * Unload the module and release the references to the device object - */ + /* + * Unload the module and release the references to the device object + */ /* Call the load/unload routine, depending on current process */ - if (DriverObject->DriverUnload && DriverObject->DriverSection && - (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER))) - { - /* Loop through each device object of the driver - and set DOE_UNLOAD_PENDING flag */ - DeviceObject = DriverObject->DeviceObject; - while (DeviceObject) - { - /* Set the unload pending flag for the device */ - DeviceExtension = IoGetDevObjExtension(DeviceObject); - DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING; + if (DriverObject->DriverUnload && DriverObject->DriverSection && + (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER))) + { + /* Loop through each device object of the driver + and set DOE_UNLOAD_PENDING flag */ + DeviceObject = DriverObject->DeviceObject; + while (DeviceObject) + { + /* Set the unload pending flag for the device */ + DeviceExtension = IoGetDevObjExtension(DeviceObject); + DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING; - /* Make sure there are no attached devices or no reference counts */ - if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice)) - { - /* Not safe to unload */ - DPRINT1("Drivers device object is referenced or has attached devices\n"); + /* Make sure there are no attached devices or no reference counts */ + if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice)) + { + /* Not safe to unload */ + DPRINT1("Drivers device object is referenced or has attached devices\n"); - SafeToUnload = FALSE; - } + SafeToUnload = FALSE; + } - DeviceObject = DeviceObject->NextDevice; - } + DeviceObject = DeviceObject->NextDevice; + } - /* If not safe to unload, then return success */ - if (!SafeToUnload) - { - ObDereferenceObject(DriverObject); - return STATUS_SUCCESS; - } + /* If not safe to unload, then return success */ + if (!SafeToUnload) + { + ObDereferenceObject(DriverObject); + return STATUS_SUCCESS; + } - DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName); + DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName); - /* Set the unload invoked flag */ - DriverObject->Flags |= DRVO_UNLOAD_INVOKED; + /* Set the unload invoked flag and call the unload routine */ + DriverObject->Flags |= DRVO_UNLOAD_INVOKED; + Status = IopLoadUnloadDriver(NULL, &DriverObject); + NT_ASSERT(Status == STATUS_SUCCESS); - if (PsGetCurrentProcess() == PsInitialSystemProcess) - { - /* Just call right away */ - (*DriverObject->DriverUnload)(DriverObject); - } - else - { - /* Load/Unload must be called from system process */ + /* Mark the driver object temporary, so it could be deleted later */ + ObMakeTemporaryObject(DriverObject); - /* Prepare parameters block */ - LoadParams.DriverObject = DriverObject; - KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE); + /* Dereference it 2 times */ + ObDereferenceObject(DriverObject); + ObDereferenceObject(DriverObject); - ExInitializeWorkItem(&LoadParams.WorkItem, - (PWORKER_THREAD_ROUTINE)IopLoadUnloadDriver, - (PVOID)&LoadParams); + return Status; + } + else + { + DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName); - /* Queue it */ - ExQueueWorkItem(&LoadParams.WorkItem, DelayedWorkQueue); + /* Dereference one time (refd inside this function) */ + ObDereferenceObject(DriverObject); - /* And wait when it completes */ - KeWaitForSingleObject(&LoadParams.Event, UserRequest, KernelMode, - FALSE, NULL); - } - - /* Mark the driver object temporary, so it could be deleted later */ - ObMakeTemporaryObject(DriverObject); - - /* Dereference it 2 times */ - ObDereferenceObject(DriverObject); - ObDereferenceObject(DriverObject); - - return STATUS_SUCCESS; - } - else - { - DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName); - - /* Dereference one time (refd inside this function) */ - ObDereferenceObject(DriverObject); - - /* Return unloading failure */ - return STATUS_INVALID_DEVICE_REQUEST; - } + /* Return unloading failure */ + return STATUS_INVALID_DEVICE_REQUEST; + } } VOID @@ -1676,8 +1661,8 @@ NTAPI IoCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL, IN PDRIVER_INITIALIZE InitializationFunction) { - PDRIVER_OBJECT DriverObject; - return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject); + PDRIVER_OBJECT DriverObject; + return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject); } /* @@ -1865,8 +1850,24 @@ IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, return DriverExtensions + 1; } -VOID NTAPI -IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) +VOID +NTAPI +IopLoadUnloadDriverWorker( + _Inout_ PVOID Parameter) +{ + PLOAD_UNLOAD_PARAMS LoadParams = Parameter; + + NT_ASSERT(PsGetCurrentProcess() == PsInitialSystemProcess); + LoadParams->Status = IopLoadUnloadDriver(LoadParams->RegistryPath, + &LoadParams->DriverObject); + KeSetEvent(&LoadParams->Event, 0, FALSE); +} + +NTSTATUS +NTAPI +IopLoadUnloadDriver( + _In_opt_ PCUNICODE_STRING RegistryPath, + _Inout_ PDRIVER_OBJECT *DriverObject) { RTL_QUERY_REGISTRY_TABLE QueryTable[3]; UNICODE_STRING ImagePath; @@ -1874,20 +1875,40 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) NTSTATUS Status; ULONG Type; PDEVICE_NODE DeviceNode; - PDRIVER_OBJECT DriverObject; PLDR_DATA_TABLE_ENTRY ModuleObject; PVOID BaseAddress; WCHAR *cur; - /* Check if it's an unload request */ - if (LoadParams->DriverObject) + /* Load/Unload must be called from system process */ + if (PsGetCurrentProcess() != PsInitialSystemProcess) { - (*LoadParams->DriverObject->DriverUnload)(LoadParams->DriverObject); + LOAD_UNLOAD_PARAMS LoadParams; - /* Return success and signal the event */ - LoadParams->Status = STATUS_SUCCESS; - KeSetEvent(&LoadParams->Event, 0, FALSE); - return; + /* Prepare parameters block */ + LoadParams.RegistryPath = RegistryPath; + LoadParams.DriverObject = *DriverObject; + KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE); + + /* Initialize and queue a work item */ + ExInitializeWorkItem(&LoadParams.WorkItem, + IopLoadUnloadDriverWorker, + &LoadParams); + ExQueueWorkItem(&LoadParams.WorkItem, DelayedWorkQueue); + + /* And wait till it completes */ + KeWaitForSingleObject(&LoadParams.Event, + UserRequest, + KernelMode, + FALSE, + NULL); + return LoadParams.Status; + } + + /* Check if it's an unload request */ + if (*DriverObject) + { + (*DriverObject)->DriverUnload(*DriverObject); + return STATUS_SUCCESS; } RtlInitUnicodeString(&ImagePath, NULL); @@ -1895,28 +1916,26 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) /* * Get the service name from the registry key name. */ - ASSERT(LoadParams->ServiceName->Length >= sizeof(WCHAR)); + ASSERT(RegistryPath->Length >= sizeof(WCHAR)); - ServiceName = *LoadParams->ServiceName; - cur = LoadParams->ServiceName->Buffer + - (LoadParams->ServiceName->Length / sizeof(WCHAR)) - 1; - while (LoadParams->ServiceName->Buffer != cur) + ServiceName = *RegistryPath; + cur = RegistryPath->Buffer + RegistryPath->Length / sizeof(WCHAR) - 1; + while (RegistryPath->Buffer != cur) { if (*cur == L'\\') { ServiceName.Buffer = cur + 1; - ServiceName.Length = LoadParams->ServiceName->Length - + ServiceName.Length = RegistryPath->Length - (USHORT)((ULONG_PTR)ServiceName.Buffer - - (ULONG_PTR)LoadParams->ServiceName->Buffer); + (ULONG_PTR)RegistryPath->Buffer); break; } cur--; } /* - * Get service type. - */ - + * Get service type. + */ RtlZeroMemory(&QueryTable, sizeof(QueryTable)); RtlInitUnicodeString(&ImagePath, NULL); @@ -1930,28 +1949,23 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) QueryTable[1].EntryContext = &ImagePath; Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - LoadParams->ServiceName->Buffer, + RegistryPath->Buffer, QueryTable, NULL, NULL); if (!NT_SUCCESS(Status)) { DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status); if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer); - LoadParams->Status = Status; - KeSetEvent(&LoadParams->Event, 0, FALSE); - return; + return Status; } /* - * Normalize the image path for all later processing. - */ - + * Normalize the image path for all later processing. + */ Status = IopNormalizeImagePath(&ImagePath, &ServiceName); if (!NT_SUCCESS(Status)) { DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status); - LoadParams->Status = Status; - KeSetEvent(&LoadParams->Event, 0, FALSE); - return; + return Status; } DPRINT("FullImagePath: '%wZ'\n", &ImagePath); @@ -1961,7 +1975,7 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) * Get existing DriverObject pointer (in case the driver * has already been loaded and initialized). */ - Status = IopGetDriverObject(&DriverObject, + Status = IopGetDriverObject(DriverObject, &ServiceName, (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ || Type == 8 /* SERVICE_RECOGNIZER_DRIVER */)); @@ -1971,15 +1985,12 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) /* * Load the driver module */ - DPRINT("Loading module from %wZ\n", &ImagePath); Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress); if (!NT_SUCCESS(Status)) { DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status); - LoadParams->Status = Status; - KeSetEvent(&LoadParams->Event, 0, FALSE); - return; + return Status; } /* @@ -1990,9 +2001,7 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) { DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status); MmUnloadSystemImage(ModuleObject); - LoadParams->Status = Status; - KeSetEvent(&LoadParams->Event, 0, FALSE); - return; + return Status; } IopDisplayLoadingMessage(&DeviceNode->ServiceName); @@ -2002,19 +2011,17 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) &DeviceNode->ServiceName, (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ || Type == 8 /* SERVICE_RECOGNIZER_DRIVER */), - &DriverObject); + DriverObject); if (!NT_SUCCESS(Status)) { DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status); MmUnloadSystemImage(ModuleObject); IopFreeDeviceNode(DeviceNode); - LoadParams->Status = Status; - KeSetEvent(&LoadParams->Event, 0, FALSE); - return; + return Status; } /* Initialize and start device */ - IopInitializeDevice(DeviceNode, DriverObject); + IopInitializeDevice(DeviceNode, *DriverObject); Status = IopStartDevice(DeviceNode); } else @@ -2023,12 +2030,10 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) Status = STATUS_IMAGE_ALREADY_LOADED; /* IopGetDriverObject references the DriverObject, so dereference it */ - ObDereferenceObject(DriverObject); + ObDereferenceObject(*DriverObject); } - /* Pass status to the caller and signal the event */ - LoadParams->Status = Status; - KeSetEvent(&LoadParams->Event, 0, FALSE); + return Status; } /* @@ -2051,7 +2056,7 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) { UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL }; KPROCESSOR_MODE PreviousMode; - LOAD_UNLOAD_PARAMS LoadParams; + PDRIVER_OBJECT DriverObject; NTSTATUS Status; PAGED_CODE(); @@ -2081,35 +2086,14 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName); - LoadParams.ServiceName = &CapturedDriverServiceName; - LoadParams.DriverObject = NULL; - KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE); - - /* Call the load/unload routine, depending on current process */ - if (PsGetCurrentProcess() == PsInitialSystemProcess) - { - /* Just call right away */ - IopLoadUnloadDriver(&LoadParams); - } - else - { - /* Load/Unload must be called from system process */ - ExInitializeWorkItem(&LoadParams.WorkItem, - (PWORKER_THREAD_ROUTINE)IopLoadUnloadDriver, - (PVOID)&LoadParams); - - /* Queue it */ - ExQueueWorkItem(&LoadParams.WorkItem, DelayedWorkQueue); - - /* And wait when it completes */ - KeWaitForSingleObject(&LoadParams.Event, UserRequest, KernelMode, - FALSE, NULL); - } + /* Load driver and call its entry point */ + DriverObject = NULL; + Status = IopLoadUnloadDriver(&CapturedDriverServiceName, &DriverObject); ReleaseCapturedUnicodeString(&CapturedDriverServiceName, PreviousMode); - return LoadParams.Status; + return Status; } /* @@ -2131,7 +2115,7 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) NTSTATUS NTAPI NtUnloadDriver(IN PUNICODE_STRING DriverServiceName) { - return IopUnloadDriver(DriverServiceName, FALSE); + return IopUnloadDriver(DriverServiceName, FALSE); } /* EOF */ diff --git a/subsystems/ntvdm/io.c b/subsystems/ntvdm/io.c index 53ff8dca14b..2fd081bd85c 100644 --- a/subsystems/ntvdm/io.c +++ b/subsystems/ntvdm/io.c @@ -70,7 +70,7 @@ IOReadB(USHORT Port) { UCHAR Data; ASSERT(Port <= MAXWORD); - IoPortProc[Port].VddIoHandlers.inb_handler((WORD)Port, &Data); + IoPortProc[Port].VddIoHandlers.inb_handler(Port, &Data); return Data; } else @@ -82,7 +82,7 @@ IOReadB(USHORT Port) } VOID -IOReadStrB(USHORT Port, +IOReadStrB(USHORT Port, PUCHAR Buffer, ULONG Count) { @@ -96,7 +96,7 @@ IOReadStrB(USHORT Port, { ASSERT(Port <= MAXWORD); ASSERT(Count <= MAXWORD); - IoPortProc[Port].VddIoHandlers.insb_handler((WORD)Port, Buffer, (WORD)Count); + IoPortProc[Port].VddIoHandlers.insb_handler(Port, Buffer, (WORD)Count); } else { @@ -106,7 +106,7 @@ IOReadStrB(USHORT Port, VOID IOWriteB(USHORT Port, - UCHAR Buffer) + UCHAR Buffer) { if (IoPortProc[Port].hVdd == INVALID_HANDLE_VALUE && IoPortProc[Port].IoHandlers.OutB) @@ -117,7 +117,7 @@ IOWriteB(USHORT Port, IoPortProc[Port].VddIoHandlers.outb_handler) { ASSERT(Port <= MAXWORD); - IoPortProc[Port].VddIoHandlers.outb_handler((WORD)Port, Buffer); + IoPortProc[Port].VddIoHandlers.outb_handler(Port, Buffer); } else { @@ -127,7 +127,7 @@ IOWriteB(USHORT Port, } VOID -IOWriteStrB(USHORT Port, +IOWriteStrB(USHORT Port, PUCHAR Buffer, ULONG Count) { @@ -141,7 +141,7 @@ IOWriteStrB(USHORT Port, { ASSERT(Port <= MAXWORD); ASSERT(Count <= MAXWORD); - IoPortProc[Port].VddIoHandlers.outsb_handler((WORD)Port, Buffer, (WORD)Count); + IoPortProc[Port].VddIoHandlers.outsb_handler(Port, Buffer, (WORD)Count); } else { @@ -162,7 +162,7 @@ IOReadW(USHORT Port) { USHORT Data; ASSERT(Port <= MAXWORD); - IoPortProc[Port].VddIoHandlers.inw_handler((WORD)Port, &Data); + IoPortProc[Port].VddIoHandlers.inw_handler(Port, &Data); return Data; } else @@ -177,7 +177,7 @@ IOReadW(USHORT Port) } VOID -IOReadStrW(USHORT Port, +IOReadStrW(USHORT Port, PUSHORT Buffer, ULONG Count) { @@ -191,7 +191,7 @@ IOReadStrW(USHORT Port, { ASSERT(Port <= MAXWORD); ASSERT(Count <= MAXWORD); - IoPortProc[Port].VddIoHandlers.insw_handler((WORD)Port, Buffer, (WORD)Count); + IoPortProc[Port].VddIoHandlers.insw_handler(Port, Buffer, (WORD)Count); } else { @@ -200,7 +200,7 @@ IOReadStrW(USHORT Port, } VOID -IOWriteW(USHORT Port, +IOWriteW(USHORT Port, USHORT Buffer) { if (IoPortProc[Port].hVdd == INVALID_HANDLE_VALUE && @@ -212,7 +212,7 @@ IOWriteW(USHORT Port, IoPortProc[Port].VddIoHandlers.outw_handler) { ASSERT(Port <= MAXWORD); - IoPortProc[Port].VddIoHandlers.outw_handler((WORD)Port, Buffer); + IoPortProc[Port].VddIoHandlers.outw_handler(Port, Buffer); } else { @@ -223,7 +223,7 @@ IOWriteW(USHORT Port, } VOID -IOWriteStrW(USHORT Port, +IOWriteStrW(USHORT Port, PUSHORT Buffer, ULONG Count) { @@ -237,7 +237,7 @@ IOWriteStrW(USHORT Port, { ASSERT(Port <= MAXWORD); ASSERT(Count <= MAXWORD); - IoPortProc[Port].VddIoHandlers.outsw_handler((WORD)Port, Buffer, (WORD)Count); + IoPortProc[Port].VddIoHandlers.outsw_handler(Port, Buffer, (WORD)Count); } else { @@ -265,7 +265,7 @@ IOReadD(USHORT Port) } VOID -IOReadStrD(USHORT Port, +IOReadStrD(USHORT Port, PULONG Buffer, ULONG Count) { @@ -282,7 +282,7 @@ IOReadStrD(USHORT Port, VOID IOWriteD(USHORT Port, - ULONG Buffer) + ULONG Buffer) { if (IoPortProc[Port].hVdd == INVALID_HANDLE_VALUE && IoPortProc[Port].IoHandlers.OutD) @@ -298,7 +298,7 @@ IOWriteD(USHORT Port, } VOID -IOWriteStrD(USHORT Port, +IOWriteStrD(USHORT Port, PULONG Buffer, ULONG Count) { diff --git a/subsystems/ntvdm/io.h b/subsystems/ntvdm/io.h index d1bde389099..33f85557cf6 100644 --- a/subsystems/ntvdm/io.h +++ b/subsystems/ntvdm/io.h @@ -36,45 +36,45 @@ typedef VOID (WINAPI *EMULATOR_OUTSD_PROC)(USHORT Port, PULONG Buffer, ULONG Co UCHAR IOReadB(USHORT Port); VOID -IOReadStrB(USHORT Port, +IOReadStrB(USHORT Port, PUCHAR Buffer, ULONG Count); VOID IOWriteB(USHORT Port, - UCHAR Buffer); + UCHAR Buffer); VOID -IOWriteStrB(USHORT Port, +IOWriteStrB(USHORT Port, PUCHAR Buffer, ULONG Count); USHORT IOReadW(USHORT Port); VOID -IOReadStrW(USHORT Port, +IOReadStrW(USHORT Port, PUSHORT Buffer, ULONG Count); VOID -IOWriteW(USHORT Port, +IOWriteW(USHORT Port, USHORT Buffer); VOID -IOWriteStrW(USHORT Port, +IOWriteStrW(USHORT Port, PUSHORT Buffer, ULONG Count); ULONG IOReadD(USHORT Port); VOID -IOReadStrD(USHORT Port, +IOReadStrD(USHORT Port, PULONG Buffer, ULONG Count); VOID IOWriteD(USHORT Port, - ULONG Buffer); + ULONG Buffer); VOID -IOWriteStrD(USHORT Port, +IOWriteStrD(USHORT Port, PULONG Buffer, ULONG Count); diff --git a/win32ss/user/ntuser/class.c b/win32ss/user/ntuser/class.c index 98e6b1a12d3..4c0db763055 100644 --- a/win32ss/user/ntuser/class.c +++ b/win32ss/user/ntuser/class.c @@ -9,7 +9,6 @@ #include DBG_DEFAULT_CHANNEL(UserClass); -BOOL FASTCALL IntClassDestroyIcon(HANDLE hCurIcon); static NTSTATUS IntDeregisterClassAtom(IN RTL_ATOM Atom); REGISTER_SYSCLASS DefaultServerClasses[] = @@ -251,7 +250,13 @@ IntDestroyClass(IN OUT PCLS Class) if (Class->spcur) UserDereferenceObject(Class->spcur); if (Class->spicnSm) + { UserDereferenceObject(Class->spicnSm); + /* Destroy the icon if we own it */ + if ((Class->CSF_flags & CSF_CACHEDSMICON) + && !(UserObjectInDestroy(UserHMGetHandle(Class->spicnSm)))) + IntDestroyCurIconObject(Class->spicnSm); + } #else if (Class->hIconSmIntern) IntClassDestroyIcon(Class->hIconSmIntern); @@ -1969,6 +1974,7 @@ UserSetClassLongPtr(IN PCLS Class, { /* We will change the small icon */ UserDereferenceObject(Class->spicnSm); + IntDestroyCurIconObject(Class->spicnSm); Class->spicnSm = NULL; Class->CSF_flags &= ~CSF_CACHEDSMICON; } @@ -1985,7 +1991,7 @@ UserSetClassLongPtr(IN PCLS Class, IMAGE_ICON, UserGetSystemMetrics( SM_CXSMICON ), UserGetSystemMetrics( SM_CYSMICON ), - LR_COPYFROMRESOURCE | LR_SHARED); + LR_COPYFROMRESOURCE); } if (!SmallIconHandle) { @@ -1995,7 +2001,7 @@ UserSetClassLongPtr(IN PCLS Class, IMAGE_ICON, UserGetSystemMetrics( SM_CXSMICON ), UserGetSystemMetrics( SM_CYSMICON ), - LR_SHARED); + 0); } if (SmallIconHandle) { @@ -2062,6 +2068,7 @@ UserSetClassLongPtr(IN PCLS Class, #ifdef NEW_CURSORICON { PCURICON_OBJECT NewSmallIcon = NULL; + BOOLEAN NewIconFromCache = FALSE; if (NewLong) { @@ -2072,10 +2079,54 @@ UserSetClassLongPtr(IN PCLS Class, return 0; } } + else + { + /* Create the new small icon from the large one */ + HICON SmallIconHandle = NULL; + if((Class->spicn->CURSORF_flags & (CURSORF_LRSHARED | CURSORF_FROMRESOURCE)) + == (CURSORF_LRSHARED | CURSORF_FROMRESOURCE)) + { + SmallIconHandle = co_IntCopyImage( + UserHMGetHandle(Class->spicn), + IMAGE_ICON, + UserGetSystemMetrics( SM_CXSMICON ), + UserGetSystemMetrics( SM_CYSMICON ), + LR_COPYFROMRESOURCE); + } + if (!SmallIconHandle) + { + /* Retry without copying from resource */ + SmallIconHandle = co_IntCopyImage( + UserHMGetHandle(Class->spicn), + IMAGE_ICON, + UserGetSystemMetrics( SM_CXSMICON ), + UserGetSystemMetrics( SM_CYSMICON ), + 0); + } + if (SmallIconHandle) + { + /* So use it */ + NewSmallIcon = UserGetCurIconObject(SmallIconHandle); + NewIconFromCache = TRUE; + } + else + { + ERR("Failed getting a small icon for the class.\n"); + } + } if (Class->spicnSm) { - Ret = (ULONG_PTR)UserHMGetHandle(Class->spicnSm); + if (Class->CSF_flags & CSF_CACHEDSMICON) + { + /* We must destroy the icon if we own it */ + IntDestroyCurIconObject(Class->spicnSm); + Ret = 0; + } + else + { + Ret = (ULONG_PTR)UserHMGetHandle(Class->spicnSm); + } UserDereferenceObject(Class->spicnSm); } else @@ -2083,7 +2134,10 @@ UserSetClassLongPtr(IN PCLS Class, Ret = 0; } - Class->CSF_flags &= ~CSF_CACHEDSMICON; + if (NewIconFromCache) + Class->CSF_flags |= CSF_CACHEDSMICON; + else + Class->CSF_flags &= ~CSF_CACHEDSMICON; Class->spicnSm = NewSmallIcon; /* Update the clones */ @@ -2094,7 +2148,10 @@ UserSetClassLongPtr(IN PCLS Class, UserDereferenceObject(Class->spicnSm); if (NewSmallIcon) UserReferenceObject(NewSmallIcon); - Class->CSF_flags &= ~CSF_CACHEDSMICON; + if (NewIconFromCache) + Class->CSF_flags |= CSF_CACHEDSMICON; + else + Class->CSF_flags &= ~CSF_CACHEDSMICON; Class->spicnSm = NewSmallIcon; Class = Class->pclsNext; } diff --git a/win32ss/user/ntuser/cursoricon_new.c b/win32ss/user/ntuser/cursoricon_new.c index 2fbfe99fb60..fb7a5c70376 100644 --- a/win32ss/user/ntuser/cursoricon_new.c +++ b/win32ss/user/ntuser/cursoricon_new.c @@ -187,7 +187,8 @@ IntDestroyCurIconObject( /* We just mark the handle as being destroyed. * Deleting all the stuff will be deferred to the actual struct free. */ - return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR); + UserDeleteObject(CurIcon->head.h, TYPE_CURSOR); + return TRUE; } void @@ -357,16 +358,18 @@ NtUserGetIconInfo( /* Get the module name from the atom table */ _SEH2_TRY { - if (BufLen > (lpModule->MaximumLength * sizeof(WCHAR))) + BufLen += sizeof(WCHAR); + if (BufLen > (lpModule->MaximumLength)) { lpModule->Length = 0; + lpModule->MaximumLength = BufLen; } else { ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1); - BufLen = lpModule->MaximumLength * sizeof(WCHAR); + BufLen = lpModule->MaximumLength; RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, lpModule->Buffer, &BufLen); - lpModule->Length = BufLen/sizeof(WCHAR); + lpModule->Length = BufLen; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -395,15 +398,18 @@ NtUserGetIconInfo( { lpResName->Buffer = CurIcon->strName.Buffer; lpResName->Length = 0; + lpResName->MaximumLength = 0; } - else if (lpResName->MaximumLength < CurIcon->strName.Length) + else if (lpResName->MaximumLength < CurIcon->strName.MaximumLength) { lpResName->Length = 0; + lpResName->MaximumLength = CurIcon->strName.MaximumLength; } else { - ProbeForWrite(lpResName->Buffer, lpResName->MaximumLength * sizeof(WCHAR), 1); - RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, lpResName->Length); + ProbeForWrite(lpResName->Buffer, lpResName->MaximumLength, 1); + RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, CurIcon->strName.Length); + lpResName->Length = CurIcon->strName.Length; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c index b04f6bad059..dd61dd2fb4e 100644 --- a/win32ss/user/ntuser/window.c +++ b/win32ss/user/ntuser/window.c @@ -1686,7 +1686,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, IMAGE_ICON, UserGetSystemMetrics( SM_CXSMICON ), UserGetSystemMetrics( SM_CYSMICON ), - LR_COPYFROMRESOURCE | LR_SHARED); + LR_COPYFROMRESOURCE); } if (!IconSmHandle) { @@ -1696,7 +1696,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, IMAGE_ICON, UserGetSystemMetrics( SM_CXSMICON ), UserGetSystemMetrics( SM_CYSMICON ), - LR_SHARED); + 0); } if (IconSmHandle) diff --git a/win32ss/user/user32/windows/cursoricon_new.c b/win32ss/user/user32/windows/cursoricon_new.c index c6810ea914c..e79c8dc831f 100644 --- a/win32ss/user/user32/windows/cursoricon_new.c +++ b/win32ss/user/user32/windows/cursoricon_new.c @@ -397,7 +397,7 @@ get_best_icon_file_entry( if ( dwFileSize < sizeof(*dir) ) return NULL; - if (dwFileSize < (sizeof(*dir) + FIELD_OFFSET(CURSORICONFILEDIR, idEntries[dir->idCount]))) + if (dwFileSize < FIELD_OFFSET(CURSORICONFILEDIR, idEntries[dir->idCount])) return NULL; /* @@ -1342,27 +1342,37 @@ CURSORICON_LoadImageW( } else RtlInitUnicodeString(&ustrRsrc, lpszName); - - /* Prepare the module name string */ - ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR)); - /* Get it */ - do + + /* Get the module name string */ + while (TRUE) { - DWORD ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size); + DWORD ret; + ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR)); + if (!ustrModule.Buffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size); if(ret == 0) { HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); return NULL; } - if(ret < size) + + /* This API is completely broken... */ + if (ret == size) { - ustrModule.Length = ret*sizeof(WCHAR); - ustrModule.MaximumLength = size*sizeof(WCHAR); - break; + HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); + size *= 2; + continue; } - size *= 2; - ustrModule.Buffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, size*sizeof(WCHAR)); - } while(TRUE); + + ustrModule.Buffer[ret] = UNICODE_NULL; + ustrModule.Length = ret * sizeof(WCHAR); + ustrModule.MaximumLength = size * sizeof(WCHAR); + break; + } /* Ask win32k */ param.bIcon = bIcon; @@ -1691,75 +1701,51 @@ CURSORICON_CopyImage( /* Get the icon module/resource names */ UNICODE_STRING ustrModule; UNICODE_STRING ustrRsrc; - PVOID pvBuf; HMODULE hModule; - ustrModule.MaximumLength = MAX_PATH * sizeof(WCHAR); - ustrRsrc.MaximumLength = 256; + ustrModule.MaximumLength = 0; + ustrRsrc.MaximumLength = 0; + /* Get the buffer size */ + if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE)) + { + return NULL; + } + ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength); if (!ustrModule.Buffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } - /* Keep track of the buffer for the resource, NtUserGetIconInfo might overwrite it */ - pvBuf = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength); - if (!pvBuf) - { - HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - ustrRsrc.Buffer = pvBuf; - do + if (ustrRsrc.MaximumLength) { - if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE)) + ustrRsrc.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength); + if (!ustrRsrc.Buffer) { HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); - HeapFree(GetProcessHeap(), 0, pvBuf); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } - - if (ustrModule.Length && (ustrRsrc.Length || IS_INTRESOURCE(ustrRsrc.Buffer))) - { - /* Buffers were big enough */ - break; - } - - /* Find which buffer were too small */ - if (!ustrModule.Length) - { - PWSTR newBuffer; - ustrModule.MaximumLength *= 2; - newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength); - if(!ustrModule.Buffer) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto leave; - } - ustrModule.Buffer = newBuffer; - } - - if (!ustrRsrc.Length) - { - ustrRsrc.MaximumLength *= 2; - pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength); - if (!pvBuf) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto leave; - } - ustrRsrc.Buffer = pvBuf; - } - } while(TRUE); + } + + if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE)) + { + HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); + if (!IS_INTRESOURCE(ustrRsrc.Buffer)) + HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer); + return NULL; + } /* NULL-terminate our strings */ - ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = 0; + ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = UNICODE_NULL; if (!IS_INTRESOURCE(ustrRsrc.Buffer)) - ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = 0; + ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = UNICODE_NULL; + TRACE("Got module %S, resource %p (%S).\n", ustrModule.Buffer, + ustrRsrc.Buffer, IS_INTRESOURCE(ustrRsrc.Buffer) ? L"" : ustrRsrc.Buffer); + /* Get the module handle */ if (!GetModuleHandleExW(0, ustrModule.Buffer, &hModule)) { @@ -1783,7 +1769,8 @@ CURSORICON_CopyImage( /* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */ leave: HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); - HeapFree(GetProcessHeap(), 0, pvBuf); + if (!IS_INTRESOURCE(ustrRsrc.Buffer)) + HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer); TRACE("Returning 0x%08x.\n", ret);