* Sync up to trunk head (r64939).

svn path=/branches/shell-experiments/; revision=64941
This commit is contained in:
Amine Khaldi 2014-10-23 19:52:45 +00:00
commit 8039ce5b7d
27 changed files with 1252 additions and 860 deletions

View file

@ -10,6 +10,7 @@ list(APPEND SOURCE
cmdPause.c cmdPause.c
cmdStart.c cmdStart.c
cmdStop.c cmdStop.c
cmdUser.c
help.c help.c
net.h) net.h)

View file

@ -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 */

View file

@ -44,7 +44,9 @@ BEGIN
IDS_TIME_HELP "TIME\n..." IDS_TIME_HELP "TIME\n..."
IDS_USE_SYNTAX "Usage:\nNET USE ..." IDS_USE_SYNTAX "Usage:\nNET USE ..."
IDS_USE_HELP "USE\n..." 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_USER_HELP "USER\n..."
IDS_VIEW_SYNTAX "Usage:\nNET VIEW ..." IDS_VIEW_SYNTAX "Usage:\nNET VIEW ..."
IDS_VIEW_HELP "VIEW\n..." IDS_VIEW_HELP "VIEW\n..."

View file

@ -50,7 +50,9 @@ BEGIN
IDS_TIME_HELP "TIME\n..." IDS_TIME_HELP "TIME\n..."
IDS_USE_SYNTAX "Utilizare:\nNET USE ..." IDS_USE_SYNTAX "Utilizare:\nNET USE ..."
IDS_USE_HELP "USE\n..." 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_USER_HELP "USER\n..."
IDS_VIEW_SYNTAX "Utilizare:\nNET VIEW ..." IDS_VIEW_SYNTAX "Utilizare:\nNET VIEW ..."
IDS_VIEW_HELP "VIEW\n..." IDS_VIEW_HELP "VIEW\n..."

View file

@ -45,7 +45,9 @@ BEGIN
IDS_TIME_HELP "TIME\n..." IDS_TIME_HELP "TIME\n..."
IDS_USE_SYNTAX "Использование:\nNET USE ..." IDS_USE_SYNTAX "Использование:\nNET USE ..."
IDS_USE_HELP "USE\n..." 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_USER_HELP "USER\n..."
IDS_VIEW_SYNTAX "Использование:\nNET VIEW ..." IDS_VIEW_SYNTAX "Использование:\nNET VIEW ..."
IDS_VIEW_HELP "VIEW\n..." IDS_VIEW_HELP "VIEW\n..."

View file

@ -40,7 +40,7 @@ COMMAND cmds[] =
{L"stop", cmdStop}, {L"stop", cmdStop},
{L"time", unimplemented}, {L"time", unimplemented},
{L"use", unimplemented}, {L"use", unimplemented},
{L"user", unimplemented}, {L"user", cmdUser},
{L"view", unimplemented}, {L"view", unimplemented},
{NULL, NULL} {NULL, NULL}
}; };

View file

@ -13,6 +13,7 @@
#include <windef.h> #include <windef.h>
#include <winbase.h> #include <winbase.h>
#include <winnls.h>
#include <winuser.h> #include <winuser.h>
#include <winsvc.h> #include <winsvc.h>
#include <stdio.h> #include <stdio.h>
@ -39,5 +40,6 @@ INT cmdLocalGroup(INT argc, WCHAR **argv);
INT cmdPause(INT argc, WCHAR **argv); INT cmdPause(INT argc, WCHAR **argv);
INT cmdStart(INT argc, WCHAR **argv); INT cmdStart(INT argc, WCHAR **argv);
INT cmdStop(INT argc, WCHAR **argv); INT cmdStop(INT argc, WCHAR **argv);
INT cmdUser(INT argc, WCHAR **argv);
#endif /* _NET_PCH_ */ #endif /* _NET_PCH_ */

View file

@ -121,6 +121,7 @@ static inline D3DVECTOR VectorBetweenTwoPoints (const D3DVECTOR *a, const D3DVEC
return c; return c;
} }
#ifndef __REACTOS__
/* calculates the length of vector's projection on another vector */ /* calculates the length of vector's projection on another vector */
static inline D3DVALUE ProjectVector (const D3DVECTOR *a, const D3DVECTOR *p) 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); p->y, p->z, result);
return result; return result;
} }
#endif
/******************************************************************************* /*******************************************************************************
* 3D Buffer and Listener mixing * 3D Buffer and Listener mixing

View file

@ -17,9 +17,6 @@ add_rpc_files(client
${REACTOS_SOURCE_DIR}/include/reactos/idl/svcctl.idl) ${REACTOS_SOURCE_DIR}/include/reactos/idl/svcctl.idl)
list(APPEND SOURCE list(APPEND SOURCE
crypt/crypt.c
crypt/crypt_des.c
crypt/crypt_lmhash.c
misc/dllmain.c misc/dllmain.c
misc/efs.c misc/efs.c
misc/hwprofiles.c misc/hwprofiles.c
@ -44,6 +41,9 @@ list(APPEND SOURCE
service/sctrl.c service/sctrl.c
token/privilege.c token/privilege.c
token/token.c token/token.c
wine/crypt.c
wine/crypt_des.c
wine/crypt_lmhash.c
advapi32.h) advapi32.h)
add_library(advapi32 SHARED add_library(advapi32 SHARED

View file

@ -39,7 +39,7 @@
#include <wine/debug.h> #include <wine/debug.h>
#include <wine/unicode.h> #include <wine/unicode.h>
#include "crypt/crypt.h" #include "wine/crypt.h"
#ifndef HAS_FN_PROGRESSW #ifndef HAS_FN_PROGRESSW
#define FN_PROGRESSW FN_PROGRESS #define FN_PROGRESSW FN_PROGRESS

View file

@ -28,10 +28,6 @@
#include <winnls.h> #include <winnls.h>
#include <shlwapi.h> #include <shlwapi.h>
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(winspool);
/****************************************************************************** /******************************************************************************
* GetDefaultPrinterA (WINSPOOL.@) * GetDefaultPrinterA (WINSPOOL.@)
*/ */

View file

@ -69,7 +69,7 @@ RemoveBatteryFromList(IN PCUNICODE_STRING BatteryName,
/* Done */ /* Done */
ExReleaseFastMutex(&DeviceExtension->Lock); ExReleaseFastMutex(&DeviceExtension->Lock);
if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING RemoveBatteryFromList\n"); if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING RemoveBatteryFromList\n");
return STATUS_SUCCESS; return NULL;
} }
BOOLEAN BOOLEAN

View file

@ -118,7 +118,7 @@ PciInitIdBuffer(IN PPCI_ID_BUFFER IdBuffer)
} }
ULONG ULONG
NTAPI __cdecl
PciIdPrintf(IN PPCI_ID_BUFFER IdBuffer, PciIdPrintf(IN PPCI_ID_BUFFER IdBuffer,
IN PCCH Format, IN PCCH Format,
...) ...)
@ -153,7 +153,7 @@ PciIdPrintf(IN PPCI_ID_BUFFER IdBuffer,
} }
ULONG ULONG
NTAPI __cdecl
PciIdPrintfAppend(IN PPCI_ID_BUFFER IdBuffer, PciIdPrintfAppend(IN PPCI_ID_BUFFER IdBuffer,
IN PCCH Format, IN PCCH Format,
...) ...)

View file

@ -256,7 +256,9 @@ check Wine current souces first as it may already be fixed.
reactos/lib/3rdparty/strmbase # Synced to Wine-1.7.27 reactos/lib/3rdparty/strmbase # Synced to Wine-1.7.27
advapi32 - advapi32 -
reactos/dll/win32/advapi32/crypt/*.c # Synced to Wine-1.7.27 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/cred.c # Synced to Wine-1.7.27
reactos/dll/win32/advapi32/sec/sid.c # Out of Sync reactos/dll/win32/advapi32/sec/sid.c # Out of Sync

View file

@ -385,7 +385,7 @@ typedef struct _OPEN_PACKET
typedef struct _LOAD_UNLOAD_PARAMS typedef struct _LOAD_UNLOAD_PARAMS
{ {
NTSTATUS Status; NTSTATUS Status;
PUNICODE_STRING ServiceName; PCUNICODE_STRING RegistryPath;
WORK_QUEUE_ITEM WorkItem; WORK_QUEUE_ITEM WorkItem;
KEVENT Event; KEVENT Event;
PDRIVER_OBJECT DriverObject; PDRIVER_OBJECT DriverObject;
@ -1083,10 +1083,11 @@ IopLoadServiceModule(
OUT PLDR_DATA_TABLE_ENTRY *ModuleObject OUT PLDR_DATA_TABLE_ENTRY *ModuleObject
); );
VOID NTSTATUS
NTAPI NTAPI
IopLoadUnloadDriver( IopLoadUnloadDriver(
IN OUT PLOAD_UNLOAD_PARAMS LoadParams _In_opt_ PCUNICODE_STRING RegistryPath,
_Inout_ PDRIVER_OBJECT *DriverObject
); );
NTSTATUS NTSTATUS

View file

@ -39,7 +39,8 @@ PLIST_ENTRY IopGroupTable;
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
NTSTATUS NTAPI NTSTATUS
NTAPI
IopInvalidDeviceRequest( IopInvalidDeviceRequest(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
@ -64,8 +65,7 @@ IopDeleteDriver(IN PVOID ObjectBody)
ASSERT(!DriverObject->DeviceObject); ASSERT(!DriverObject->DeviceObject);
/* Get the extension and loop them */ /* Get the extension and loop them */
DriverExtension = IoGetDrvObjExtension(DriverObject)-> DriverExtension = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
ClientDriverExtension;
while (DriverExtension) while (DriverExtension)
{ {
/* Get the next one */ /* Get the next one */
@ -98,7 +98,8 @@ IopDeleteDriver(IN PVOID ObjectBody)
} }
} }
NTSTATUS FASTCALL NTSTATUS
FASTCALL
IopGetDriverObject( IopGetDriverObject(
PDRIVER_OBJECT *DriverObject, PDRIVER_OBJECT *DriverObject,
PUNICODE_STRING ServiceName, PUNICODE_STRING ServiceName,
@ -132,8 +133,7 @@ IopGetDriverObject(
DPRINT("Driver name: '%wZ'\n", &DriverName); DPRINT("Driver name: '%wZ'\n", &DriverName);
/* Open driver object */ /* Open driver object */
Status = ObReferenceObjectByName( Status = ObReferenceObjectByName(&DriverName,
&DriverName,
OBJ_OPENIF | OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, /* Attributes */ OBJ_OPENIF | OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, /* Attributes */
NULL, /* PassedAccessState */ NULL, /* PassedAccessState */
0, /* DesiredAccess */ 0, /* DesiredAccess */
@ -141,7 +141,6 @@ IopGetDriverObject(
KernelMode, KernelMode,
NULL, /* ParseContext */ NULL, /* ParseContext */
(PVOID*)&Object); (PVOID*)&Object);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("Failed to reference driver object, status=0x%08x\n", Status); DPRINT("Failed to reference driver object, status=0x%08x\n", Status);
@ -193,7 +192,6 @@ IopSuffixUnicodeString(
* *
* Display 'Loading XXX...' message. * Display 'Loading XXX...' message.
*/ */
VOID VOID
FASTCALL FASTCALL
INIT_FUNCTION INIT_FUNCTION
@ -234,7 +232,6 @@ IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
* Remarks * Remarks
* The input image path isn't freed on error. * The input image path isn't freed on error.
*/ */
NTSTATUS NTSTATUS
FASTCALL FASTCALL
IopNormalizeImagePath( IopNormalizeImagePath(
@ -246,8 +243,7 @@ IopNormalizeImagePath(
DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName); DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
RtlCopyMemory( RtlCopyMemory(&InputImagePath,
&InputImagePath,
ImagePath, ImagePath,
sizeof(UNICODE_STRING)); sizeof(UNICODE_STRING));
@ -256,20 +252,22 @@ IopNormalizeImagePath(
ImagePath->Length = 0; ImagePath->Length = 0;
ImagePath->MaximumLength = ImagePath->MaximumLength =
(33 * sizeof(WCHAR)) + ServiceName->Length + sizeof(UNICODE_NULL); (33 * sizeof(WCHAR)) + ServiceName->Length + sizeof(UNICODE_NULL);
ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength); ImagePath->Buffer = ExAllocatePool(NonPagedPool,
ImagePath->MaximumLength);
if (ImagePath->Buffer == NULL) if (ImagePath->Buffer == NULL)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\system32\\drivers\\"); RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\system32\\drivers\\");
RtlAppendUnicodeStringToString(ImagePath, ServiceName); RtlAppendUnicodeStringToString(ImagePath, ServiceName);
RtlAppendUnicodeToString(ImagePath, L".sys"); RtlAppendUnicodeToString(ImagePath, L".sys");
} else }
if (InputImagePath.Buffer[0] != L'\\') else if (InputImagePath.Buffer[0] != L'\\')
{ {
ImagePath->Length = 0; ImagePath->Length = 0;
ImagePath->MaximumLength = ImagePath->MaximumLength =
12 * sizeof(WCHAR) + InputImagePath.Length + sizeof(UNICODE_NULL); 12 * sizeof(WCHAR) + InputImagePath.Length + sizeof(UNICODE_NULL);
ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength); ImagePath->Buffer = ExAllocatePool(NonPagedPool,
ImagePath->MaximumLength);
if (ImagePath->Buffer == NULL) if (ImagePath->Buffer == NULL)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
@ -297,8 +295,8 @@ IopNormalizeImagePath(
* Return Value * Return Value
* Status * Status
*/ */
NTSTATUS
NTSTATUS FASTCALL FASTCALL
IopLoadServiceModule( IopLoadServiceModule(
IN PUNICODE_STRING ServiceName, IN PUNICODE_STRING ServiceName,
OUT PLDR_DATA_TABLE_ENTRY *ModuleObject) OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
@ -350,7 +348,6 @@ IopLoadServiceModule(
/* /*
* Get information about the service. * Get information about the service.
*/ */
RtlZeroMemory(QueryTable, sizeof(QueryTable)); RtlZeroMemory(QueryTable, sizeof(QueryTable));
RtlInitUnicodeString(&ServiceImagePath, NULL); RtlInitUnicodeString(&ServiceImagePath, NULL);
@ -364,7 +361,10 @@ IopLoadServiceModule(
QueryTable[1].EntryContext = &ServiceImagePath; QueryTable[1].EntryContext = &ServiceImagePath;
Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
(PWSTR)ServiceKey, QueryTable, NULL, NULL); (PWSTR)ServiceKey,
QueryTable,
NULL,
NULL);
ZwClose(ServiceKey); ZwClose(ServiceKey);
ZwClose(CCSKey); ZwClose(CCSKey);
@ -379,7 +379,6 @@ IopLoadServiceModule(
/* /*
* Normalize the image path for all later processing. * Normalize the image path for all later processing.
*/ */
Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName); Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -391,7 +390,6 @@ IopLoadServiceModule(
/* /*
* Case for disabled drivers * Case for disabled drivers
*/ */
if (ServiceStart >= 4) if (ServiceStart >= 4)
{ {
/* We can't load this */ /* We can't load this */
@ -412,7 +410,6 @@ IopLoadServiceModule(
/* /*
* Now check if the module was loaded successfully. * Now check if the module was loaded successfully.
*/ */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("Module loading failed (Status %x)\n", Status); DPRINT("Module loading failed (Status %x)\n", Status);
@ -450,8 +447,8 @@ MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
* On successful return this contains the driver object representing * On successful return this contains the driver object representing
* the loaded driver. * the loaded driver.
*/ */
NTSTATUS
NTSTATUS FASTCALL FASTCALL
IopInitializeDriverModule( IopInitializeDriverModule(
IN PDEVICE_NODE DeviceNode, IN PDEVICE_NODE DeviceNode,
IN PLDR_DATA_TABLE_ENTRY ModuleObject, IN PLDR_DATA_TABLE_ENTRY ModuleObject,
@ -504,8 +501,7 @@ IopInitializeDriverModule(
else else
DriverName.Length = 0; DriverName.Length = 0;
Status = IopCreateDriver( Status = IopCreateDriver(DriverName.Length > 0 ? &DriverName : NULL,
DriverName.Length > 0 ? &DriverName : NULL,
DriverEntry, DriverEntry,
&RegistryKey, &RegistryKey,
ServiceName, ServiceName,
@ -535,8 +531,8 @@ IopInitializeDriverModule(
* *
* Internal routine used by IopAttachFilterDrivers. * Internal routine used by IopAttachFilterDrivers.
*/ */
NTSTATUS
NTSTATUS NTAPI NTAPI
IopAttachFilterDriversCallback( IopAttachFilterDriversCallback(
PWSTR ValueName, PWSTR ValueName,
ULONG ValueType, ULONG ValueType,
@ -577,8 +573,11 @@ IopAttachFilterDriversCallback(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return Status;
Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName, Status = IopInitializeDriverModule(DeviceNode,
FALSE, &DriverObject); ModuleObject,
&ServiceName,
FALSE,
&DriverObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return Status;
} }
@ -605,8 +604,8 @@ IopAttachFilterDriversCallback(
* Set to TRUE for loading lower level filters or FALSE for upper * Set to TRUE for loading lower level filters or FALSE for upper
* level filters. * level filters.
*/ */
NTSTATUS
NTSTATUS FASTCALL FASTCALL
IopAttachFilterDrivers( IopAttachFilterDrivers(
PDEVICE_NODE DeviceNode, PDEVICE_NODE DeviceNode,
BOOLEAN Lower) BOOLEAN Lower)
@ -619,8 +618,10 @@ IopAttachFilterDrivers(
NTSTATUS Status; NTSTATUS Status;
/* Open enumeration root key */ /* Open enumeration root key */
Status = IopOpenRegistryKeyEx(&EnumRootKey, NULL, Status = IopOpenRegistryKeyEx(&EnumRootKey,
&EnumRoot, KEY_READ); NULL,
&EnumRoot,
KEY_READ);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
@ -628,8 +629,10 @@ IopAttachFilterDrivers(
} }
/* Open subkey */ /* Open subkey */
Status = IopOpenRegistryKeyEx(&SubKey, EnumRootKey, Status = IopOpenRegistryKeyEx(&SubKey,
&DeviceNode->InstancePath, KEY_READ); EnumRootKey,
&DeviceNode->InstancePath,
KEY_READ);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
@ -648,8 +651,7 @@ IopAttachFilterDrivers(
QueryTable[0].Flags = 0; QueryTable[0].Flags = 0;
QueryTable[0].DefaultType = REG_NONE; QueryTable[0].DefaultType = REG_NONE;
Status = RtlQueryRegistryValues( Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
RTL_REGISTRY_HANDLE,
(PWSTR)SubKey, (PWSTR)SubKey,
QueryTable, QueryTable,
DeviceNode, DeviceNode,
@ -674,8 +676,7 @@ IopAttachFilterDrivers(
QueryTable[0].EntryContext = &Class; QueryTable[0].EntryContext = &Class;
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
Status = RtlQueryRegistryValues( Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
RTL_REGISTRY_HANDLE,
(PWSTR)SubKey, (PWSTR)SubKey,
QueryTable, QueryTable,
DeviceNode, DeviceNode,
@ -692,8 +693,10 @@ IopAttachFilterDrivers(
{ {
UNICODE_STRING ControlClass = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class"); UNICODE_STRING ControlClass = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class");
Status = IopOpenRegistryKeyEx(&EnumRootKey, NULL, Status = IopOpenRegistryKeyEx(&EnumRootKey,
&ControlClass, KEY_READ); NULL,
&ControlClass,
KEY_READ);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status); DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
@ -701,8 +704,10 @@ IopAttachFilterDrivers(
} }
/* Open subkey */ /* Open subkey */
Status = IopOpenRegistryKeyEx(&SubKey, EnumRootKey, Status = IopOpenRegistryKeyEx(&SubKey,
&Class, KEY_READ); EnumRootKey,
&Class,
KEY_READ);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* It's okay if there's no class key */ /* It's okay if there's no class key */
@ -720,8 +725,7 @@ IopAttachFilterDrivers(
QueryTable[0].Flags = 0; QueryTable[0].Flags = 0;
QueryTable[0].DefaultType = REG_NONE; QueryTable[0].DefaultType = REG_NONE;
Status = RtlQueryRegistryValues( Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
RTL_REGISTRY_HANDLE,
(PWSTR)SubKey, (PWSTR)SubKey,
QueryTable, QueryTable,
DeviceNode, DeviceNode,
@ -836,7 +840,6 @@ LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry,
* *
* Initialize a driver that is already loaded in memory. * Initialize a driver that is already loaded in memory.
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
INIT_FUNCTION INIT_FUNCTION
@ -886,7 +889,10 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
* Determine the right device object * Determine the right device object
*/ */
/* Use IopRootDeviceNode for now */ /* Use IopRootDeviceNode for now */
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode); Status = IopCreateDeviceNode(IopRootDeviceNode,
NULL,
&ServiceName,
&DeviceNode);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status); DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
@ -912,8 +918,11 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
/* /*
* Initialize the driver * Initialize the driver
*/ */
Status = IopInitializeDriverModule(DeviceNode, LdrEntry, Status = IopInitializeDriverModule(DeviceNode,
&DeviceNode->ServiceName, FALSE, &DriverObject); LdrEntry,
&DeviceNode->ServiceName,
FALSE,
&DriverObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -1202,7 +1211,6 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
PDRIVER_OBJECT DriverObject; PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PEXTENDED_DEVOBJ_EXTENSION DeviceExtension; PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
LOAD_UNLOAD_PARAMS LoadParams;
NTSTATUS Status; NTSTATUS Status;
LPWSTR Start; LPWSTR Start;
BOOLEAN SafeToUnload = TRUE; BOOLEAN SafeToUnload = TRUE;
@ -1270,7 +1278,6 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
/* /*
* Get path of service... * Get path of service...
*/ */
RtlZeroMemory(QueryTable, sizeof(QueryTable)); RtlZeroMemory(QueryTable, sizeof(QueryTable));
RtlInitUnicodeString(&ImagePath, NULL); RtlInitUnicodeString(&ImagePath, NULL);
@ -1280,7 +1287,10 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
QueryTable[0].EntryContext = &ImagePath; QueryTable[0].EntryContext = &ImagePath;
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
DriverServiceName->Buffer, QueryTable, NULL, NULL); DriverServiceName->Buffer,
QueryTable,
NULL,
NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -1292,7 +1302,6 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
/* /*
* Normalize the image path for all later processing. * Normalize the image path for all later processing.
*/ */
Status = IopNormalizeImagePath(&ImagePath, &ServiceName); Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -1305,7 +1314,6 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
/* /*
* Free the service path * Free the service path
*/ */
ExFreePool(ImagePath.Buffer); ExFreePool(ImagePath.Buffer);
/* /*
@ -1346,33 +1354,10 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName); DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
/* Set the unload invoked flag */ /* Set the unload invoked flag and call the unload routine */
DriverObject->Flags |= DRVO_UNLOAD_INVOKED; DriverObject->Flags |= DRVO_UNLOAD_INVOKED;
Status = IopLoadUnloadDriver(NULL, &DriverObject);
if (PsGetCurrentProcess() == PsInitialSystemProcess) NT_ASSERT(Status == STATUS_SUCCESS);
{
/* Just call right away */
(*DriverObject->DriverUnload)(DriverObject);
}
else
{
/* Load/Unload must be called from system process */
/* Prepare parameters block */
LoadParams.DriverObject = DriverObject;
KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE);
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);
}
/* Mark the driver object temporary, so it could be deleted later */ /* Mark the driver object temporary, so it could be deleted later */
ObMakeTemporaryObject(DriverObject); ObMakeTemporaryObject(DriverObject);
@ -1381,7 +1366,7 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
ObDereferenceObject(DriverObject); ObDereferenceObject(DriverObject);
ObDereferenceObject(DriverObject); ObDereferenceObject(DriverObject);
return STATUS_SUCCESS; return Status;
} }
else else
{ {
@ -1865,8 +1850,24 @@ IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject,
return DriverExtensions + 1; return DriverExtensions + 1;
} }
VOID NTAPI VOID
IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) 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]; RTL_QUERY_REGISTRY_TABLE QueryTable[3];
UNICODE_STRING ImagePath; UNICODE_STRING ImagePath;
@ -1874,20 +1875,40 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
NTSTATUS Status; NTSTATUS Status;
ULONG Type; ULONG Type;
PDEVICE_NODE DeviceNode; PDEVICE_NODE DeviceNode;
PDRIVER_OBJECT DriverObject;
PLDR_DATA_TABLE_ENTRY ModuleObject; PLDR_DATA_TABLE_ENTRY ModuleObject;
PVOID BaseAddress; PVOID BaseAddress;
WCHAR *cur; WCHAR *cur;
/* Check if it's an unload request */ /* Load/Unload must be called from system process */
if (LoadParams->DriverObject) if (PsGetCurrentProcess() != PsInitialSystemProcess)
{ {
(*LoadParams->DriverObject->DriverUnload)(LoadParams->DriverObject); LOAD_UNLOAD_PARAMS LoadParams;
/* Return success and signal the event */ /* Prepare parameters block */
LoadParams->Status = STATUS_SUCCESS; LoadParams.RegistryPath = RegistryPath;
KeSetEvent(&LoadParams->Event, 0, FALSE); LoadParams.DriverObject = *DriverObject;
return; 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); RtlInitUnicodeString(&ImagePath, NULL);
@ -1895,19 +1916,18 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
/* /*
* Get the service name from the registry key name. * Get the service name from the registry key name.
*/ */
ASSERT(LoadParams->ServiceName->Length >= sizeof(WCHAR)); ASSERT(RegistryPath->Length >= sizeof(WCHAR));
ServiceName = *LoadParams->ServiceName; ServiceName = *RegistryPath;
cur = LoadParams->ServiceName->Buffer + cur = RegistryPath->Buffer + RegistryPath->Length / sizeof(WCHAR) - 1;
(LoadParams->ServiceName->Length / sizeof(WCHAR)) - 1; while (RegistryPath->Buffer != cur)
while (LoadParams->ServiceName->Buffer != cur)
{ {
if (*cur == L'\\') if (*cur == L'\\')
{ {
ServiceName.Buffer = cur + 1; ServiceName.Buffer = cur + 1;
ServiceName.Length = LoadParams->ServiceName->Length - ServiceName.Length = RegistryPath->Length -
(USHORT)((ULONG_PTR)ServiceName.Buffer - (USHORT)((ULONG_PTR)ServiceName.Buffer -
(ULONG_PTR)LoadParams->ServiceName->Buffer); (ULONG_PTR)RegistryPath->Buffer);
break; break;
} }
cur--; cur--;
@ -1916,7 +1936,6 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
/* /*
* Get service type. * Get service type.
*/ */
RtlZeroMemory(&QueryTable, sizeof(QueryTable)); RtlZeroMemory(&QueryTable, sizeof(QueryTable));
RtlInitUnicodeString(&ImagePath, NULL); RtlInitUnicodeString(&ImagePath, NULL);
@ -1930,28 +1949,23 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
QueryTable[1].EntryContext = &ImagePath; QueryTable[1].EntryContext = &ImagePath;
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
LoadParams->ServiceName->Buffer, RegistryPath->Buffer,
QueryTable, NULL, NULL); QueryTable, NULL, NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status); DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer); if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer);
LoadParams->Status = Status; return Status;
KeSetEvent(&LoadParams->Event, 0, FALSE);
return;
} }
/* /*
* Normalize the image path for all later processing. * Normalize the image path for all later processing.
*/ */
Status = IopNormalizeImagePath(&ImagePath, &ServiceName); Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status); DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
LoadParams->Status = Status; return Status;
KeSetEvent(&LoadParams->Event, 0, FALSE);
return;
} }
DPRINT("FullImagePath: '%wZ'\n", &ImagePath); DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
@ -1961,7 +1975,7 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
* Get existing DriverObject pointer (in case the driver * Get existing DriverObject pointer (in case the driver
* has already been loaded and initialized). * has already been loaded and initialized).
*/ */
Status = IopGetDriverObject(&DriverObject, Status = IopGetDriverObject(DriverObject,
&ServiceName, &ServiceName,
(Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ || (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
Type == 8 /* SERVICE_RECOGNIZER_DRIVER */)); Type == 8 /* SERVICE_RECOGNIZER_DRIVER */));
@ -1971,15 +1985,12 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
/* /*
* Load the driver module * Load the driver module
*/ */
DPRINT("Loading module from %wZ\n", &ImagePath); DPRINT("Loading module from %wZ\n", &ImagePath);
Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress); Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status); DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
LoadParams->Status = Status; return Status;
KeSetEvent(&LoadParams->Event, 0, FALSE);
return;
} }
/* /*
@ -1990,9 +2001,7 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
{ {
DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status); DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
MmUnloadSystemImage(ModuleObject); MmUnloadSystemImage(ModuleObject);
LoadParams->Status = Status; return Status;
KeSetEvent(&LoadParams->Event, 0, FALSE);
return;
} }
IopDisplayLoadingMessage(&DeviceNode->ServiceName); IopDisplayLoadingMessage(&DeviceNode->ServiceName);
@ -2002,19 +2011,17 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
&DeviceNode->ServiceName, &DeviceNode->ServiceName,
(Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ || (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
Type == 8 /* SERVICE_RECOGNIZER_DRIVER */), Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
&DriverObject); DriverObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status); DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
MmUnloadSystemImage(ModuleObject); MmUnloadSystemImage(ModuleObject);
IopFreeDeviceNode(DeviceNode); IopFreeDeviceNode(DeviceNode);
LoadParams->Status = Status; return Status;
KeSetEvent(&LoadParams->Event, 0, FALSE);
return;
} }
/* Initialize and start device */ /* Initialize and start device */
IopInitializeDevice(DeviceNode, DriverObject); IopInitializeDevice(DeviceNode, *DriverObject);
Status = IopStartDevice(DeviceNode); Status = IopStartDevice(DeviceNode);
} }
else else
@ -2023,12 +2030,10 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
Status = STATUS_IMAGE_ALREADY_LOADED; Status = STATUS_IMAGE_ALREADY_LOADED;
/* IopGetDriverObject references the DriverObject, so dereference it */ /* IopGetDriverObject references the DriverObject, so dereference it */
ObDereferenceObject(DriverObject); ObDereferenceObject(*DriverObject);
} }
/* Pass status to the caller and signal the event */ return Status;
LoadParams->Status = Status;
KeSetEvent(&LoadParams->Event, 0, FALSE);
} }
/* /*
@ -2051,7 +2056,7 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
{ {
UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL }; UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL };
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
LOAD_UNLOAD_PARAMS LoadParams; PDRIVER_OBJECT DriverObject;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
@ -2081,35 +2086,14 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName); DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName);
LoadParams.ServiceName = &CapturedDriverServiceName; /* Load driver and call its entry point */
LoadParams.DriverObject = NULL; DriverObject = NULL;
KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE); Status = IopLoadUnloadDriver(&CapturedDriverServiceName, &DriverObject);
/* 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);
}
ReleaseCapturedUnicodeString(&CapturedDriverServiceName, ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
PreviousMode); PreviousMode);
return LoadParams.Status; return Status;
} }
/* /*

View file

@ -70,7 +70,7 @@ IOReadB(USHORT Port)
{ {
UCHAR Data; UCHAR Data;
ASSERT(Port <= MAXWORD); ASSERT(Port <= MAXWORD);
IoPortProc[Port].VddIoHandlers.inb_handler((WORD)Port, &Data); IoPortProc[Port].VddIoHandlers.inb_handler(Port, &Data);
return Data; return Data;
} }
else else
@ -96,7 +96,7 @@ IOReadStrB(USHORT Port,
{ {
ASSERT(Port <= MAXWORD); ASSERT(Port <= MAXWORD);
ASSERT(Count <= MAXWORD); ASSERT(Count <= MAXWORD);
IoPortProc[Port].VddIoHandlers.insb_handler((WORD)Port, Buffer, (WORD)Count); IoPortProc[Port].VddIoHandlers.insb_handler(Port, Buffer, (WORD)Count);
} }
else else
{ {
@ -117,7 +117,7 @@ IOWriteB(USHORT Port,
IoPortProc[Port].VddIoHandlers.outb_handler) IoPortProc[Port].VddIoHandlers.outb_handler)
{ {
ASSERT(Port <= MAXWORD); ASSERT(Port <= MAXWORD);
IoPortProc[Port].VddIoHandlers.outb_handler((WORD)Port, Buffer); IoPortProc[Port].VddIoHandlers.outb_handler(Port, Buffer);
} }
else else
{ {
@ -141,7 +141,7 @@ IOWriteStrB(USHORT Port,
{ {
ASSERT(Port <= MAXWORD); ASSERT(Port <= MAXWORD);
ASSERT(Count <= MAXWORD); ASSERT(Count <= MAXWORD);
IoPortProc[Port].VddIoHandlers.outsb_handler((WORD)Port, Buffer, (WORD)Count); IoPortProc[Port].VddIoHandlers.outsb_handler(Port, Buffer, (WORD)Count);
} }
else else
{ {
@ -162,7 +162,7 @@ IOReadW(USHORT Port)
{ {
USHORT Data; USHORT Data;
ASSERT(Port <= MAXWORD); ASSERT(Port <= MAXWORD);
IoPortProc[Port].VddIoHandlers.inw_handler((WORD)Port, &Data); IoPortProc[Port].VddIoHandlers.inw_handler(Port, &Data);
return Data; return Data;
} }
else else
@ -191,7 +191,7 @@ IOReadStrW(USHORT Port,
{ {
ASSERT(Port <= MAXWORD); ASSERT(Port <= MAXWORD);
ASSERT(Count <= MAXWORD); ASSERT(Count <= MAXWORD);
IoPortProc[Port].VddIoHandlers.insw_handler((WORD)Port, Buffer, (WORD)Count); IoPortProc[Port].VddIoHandlers.insw_handler(Port, Buffer, (WORD)Count);
} }
else else
{ {
@ -212,7 +212,7 @@ IOWriteW(USHORT Port,
IoPortProc[Port].VddIoHandlers.outw_handler) IoPortProc[Port].VddIoHandlers.outw_handler)
{ {
ASSERT(Port <= MAXWORD); ASSERT(Port <= MAXWORD);
IoPortProc[Port].VddIoHandlers.outw_handler((WORD)Port, Buffer); IoPortProc[Port].VddIoHandlers.outw_handler(Port, Buffer);
} }
else else
{ {
@ -237,7 +237,7 @@ IOWriteStrW(USHORT Port,
{ {
ASSERT(Port <= MAXWORD); ASSERT(Port <= MAXWORD);
ASSERT(Count <= MAXWORD); ASSERT(Count <= MAXWORD);
IoPortProc[Port].VddIoHandlers.outsw_handler((WORD)Port, Buffer, (WORD)Count); IoPortProc[Port].VddIoHandlers.outsw_handler(Port, Buffer, (WORD)Count);
} }
else else
{ {

View file

@ -9,7 +9,6 @@
#include <win32k.h> #include <win32k.h>
DBG_DEFAULT_CHANNEL(UserClass); DBG_DEFAULT_CHANNEL(UserClass);
BOOL FASTCALL IntClassDestroyIcon(HANDLE hCurIcon);
static NTSTATUS IntDeregisterClassAtom(IN RTL_ATOM Atom); static NTSTATUS IntDeregisterClassAtom(IN RTL_ATOM Atom);
REGISTER_SYSCLASS DefaultServerClasses[] = REGISTER_SYSCLASS DefaultServerClasses[] =
@ -251,7 +250,13 @@ IntDestroyClass(IN OUT PCLS Class)
if (Class->spcur) if (Class->spcur)
UserDereferenceObject(Class->spcur); UserDereferenceObject(Class->spcur);
if (Class->spicnSm) if (Class->spicnSm)
{
UserDereferenceObject(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 #else
if (Class->hIconSmIntern) if (Class->hIconSmIntern)
IntClassDestroyIcon(Class->hIconSmIntern); IntClassDestroyIcon(Class->hIconSmIntern);
@ -1969,6 +1974,7 @@ UserSetClassLongPtr(IN PCLS Class,
{ {
/* We will change the small icon */ /* We will change the small icon */
UserDereferenceObject(Class->spicnSm); UserDereferenceObject(Class->spicnSm);
IntDestroyCurIconObject(Class->spicnSm);
Class->spicnSm = NULL; Class->spicnSm = NULL;
Class->CSF_flags &= ~CSF_CACHEDSMICON; Class->CSF_flags &= ~CSF_CACHEDSMICON;
} }
@ -1985,7 +1991,7 @@ UserSetClassLongPtr(IN PCLS Class,
IMAGE_ICON, IMAGE_ICON,
UserGetSystemMetrics( SM_CXSMICON ), UserGetSystemMetrics( SM_CXSMICON ),
UserGetSystemMetrics( SM_CYSMICON ), UserGetSystemMetrics( SM_CYSMICON ),
LR_COPYFROMRESOURCE | LR_SHARED); LR_COPYFROMRESOURCE);
} }
if (!SmallIconHandle) if (!SmallIconHandle)
{ {
@ -1995,7 +2001,7 @@ UserSetClassLongPtr(IN PCLS Class,
IMAGE_ICON, IMAGE_ICON,
UserGetSystemMetrics( SM_CXSMICON ), UserGetSystemMetrics( SM_CXSMICON ),
UserGetSystemMetrics( SM_CYSMICON ), UserGetSystemMetrics( SM_CYSMICON ),
LR_SHARED); 0);
} }
if (SmallIconHandle) if (SmallIconHandle)
{ {
@ -2062,6 +2068,7 @@ UserSetClassLongPtr(IN PCLS Class,
#ifdef NEW_CURSORICON #ifdef NEW_CURSORICON
{ {
PCURICON_OBJECT NewSmallIcon = NULL; PCURICON_OBJECT NewSmallIcon = NULL;
BOOLEAN NewIconFromCache = FALSE;
if (NewLong) if (NewLong)
{ {
@ -2072,10 +2079,54 @@ UserSetClassLongPtr(IN PCLS Class,
return 0; 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) if (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); Ret = (ULONG_PTR)UserHMGetHandle(Class->spicnSm);
}
UserDereferenceObject(Class->spicnSm); UserDereferenceObject(Class->spicnSm);
} }
else else
@ -2083,6 +2134,9 @@ UserSetClassLongPtr(IN PCLS Class,
Ret = 0; Ret = 0;
} }
if (NewIconFromCache)
Class->CSF_flags |= CSF_CACHEDSMICON;
else
Class->CSF_flags &= ~CSF_CACHEDSMICON; Class->CSF_flags &= ~CSF_CACHEDSMICON;
Class->spicnSm = NewSmallIcon; Class->spicnSm = NewSmallIcon;
@ -2094,6 +2148,9 @@ UserSetClassLongPtr(IN PCLS Class,
UserDereferenceObject(Class->spicnSm); UserDereferenceObject(Class->spicnSm);
if (NewSmallIcon) if (NewSmallIcon)
UserReferenceObject(NewSmallIcon); UserReferenceObject(NewSmallIcon);
if (NewIconFromCache)
Class->CSF_flags |= CSF_CACHEDSMICON;
else
Class->CSF_flags &= ~CSF_CACHEDSMICON; Class->CSF_flags &= ~CSF_CACHEDSMICON;
Class->spicnSm = NewSmallIcon; Class->spicnSm = NewSmallIcon;
Class = Class->pclsNext; Class = Class->pclsNext;

View file

@ -187,7 +187,8 @@ IntDestroyCurIconObject(
/* We just mark the handle as being destroyed. /* We just mark the handle as being destroyed.
* Deleting all the stuff will be deferred to the actual struct free. */ * 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 void
@ -357,16 +358,18 @@ NtUserGetIconInfo(
/* Get the module name from the atom table */ /* Get the module name from the atom table */
_SEH2_TRY _SEH2_TRY
{ {
if (BufLen > (lpModule->MaximumLength * sizeof(WCHAR))) BufLen += sizeof(WCHAR);
if (BufLen > (lpModule->MaximumLength))
{ {
lpModule->Length = 0; lpModule->Length = 0;
lpModule->MaximumLength = BufLen;
} }
else else
{ {
ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1); ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1);
BufLen = lpModule->MaximumLength * sizeof(WCHAR); BufLen = lpModule->MaximumLength;
RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, lpModule->Buffer, &BufLen); RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, lpModule->Buffer, &BufLen);
lpModule->Length = BufLen/sizeof(WCHAR); lpModule->Length = BufLen;
} }
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@ -395,15 +398,18 @@ NtUserGetIconInfo(
{ {
lpResName->Buffer = CurIcon->strName.Buffer; lpResName->Buffer = CurIcon->strName.Buffer;
lpResName->Length = 0; lpResName->Length = 0;
lpResName->MaximumLength = 0;
} }
else if (lpResName->MaximumLength < CurIcon->strName.Length) else if (lpResName->MaximumLength < CurIcon->strName.MaximumLength)
{ {
lpResName->Length = 0; lpResName->Length = 0;
lpResName->MaximumLength = CurIcon->strName.MaximumLength;
} }
else else
{ {
ProbeForWrite(lpResName->Buffer, lpResName->MaximumLength * sizeof(WCHAR), 1); ProbeForWrite(lpResName->Buffer, lpResName->MaximumLength, 1);
RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, lpResName->Length); RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, CurIcon->strName.Length);
lpResName->Length = CurIcon->strName.Length;
} }
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

View file

@ -1686,7 +1686,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
IMAGE_ICON, IMAGE_ICON,
UserGetSystemMetrics( SM_CXSMICON ), UserGetSystemMetrics( SM_CXSMICON ),
UserGetSystemMetrics( SM_CYSMICON ), UserGetSystemMetrics( SM_CYSMICON ),
LR_COPYFROMRESOURCE | LR_SHARED); LR_COPYFROMRESOURCE);
} }
if (!IconSmHandle) if (!IconSmHandle)
{ {
@ -1696,7 +1696,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
IMAGE_ICON, IMAGE_ICON,
UserGetSystemMetrics( SM_CXSMICON ), UserGetSystemMetrics( SM_CXSMICON ),
UserGetSystemMetrics( SM_CYSMICON ), UserGetSystemMetrics( SM_CYSMICON ),
LR_SHARED); 0);
} }
if (IconSmHandle) if (IconSmHandle)

View file

@ -397,7 +397,7 @@ get_best_icon_file_entry(
if ( dwFileSize < sizeof(*dir) ) if ( dwFileSize < sizeof(*dir) )
return NULL; return NULL;
if (dwFileSize < (sizeof(*dir) + FIELD_OFFSET(CURSORICONFILEDIR, idEntries[dir->idCount]))) if (dwFileSize < FIELD_OFFSET(CURSORICONFILEDIR, idEntries[dir->idCount]))
return NULL; return NULL;
/* /*
@ -1343,26 +1343,36 @@ CURSORICON_LoadImageW(
else else
RtlInitUnicodeString(&ustrRsrc, lpszName); RtlInitUnicodeString(&ustrRsrc, lpszName);
/* Prepare the module name string */ /* Get the module name string */
ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR)); while (TRUE)
/* Get it */
do
{ {
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) if(ret == 0)
{ {
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
return NULL; return NULL;
} }
if(ret < size)
/* This API is completely broken... */
if (ret == size)
{ {
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
size *= 2;
continue;
}
ustrModule.Buffer[ret] = UNICODE_NULL;
ustrModule.Length = ret * sizeof(WCHAR); ustrModule.Length = ret * sizeof(WCHAR);
ustrModule.MaximumLength = size * sizeof(WCHAR); ustrModule.MaximumLength = size * sizeof(WCHAR);
break; break;
} }
size *= 2;
ustrModule.Buffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, size*sizeof(WCHAR));
} while(TRUE);
/* Ask win32k */ /* Ask win32k */
param.bIcon = bIcon; param.bIcon = bIcon;
@ -1691,11 +1701,16 @@ CURSORICON_CopyImage(
/* Get the icon module/resource names */ /* Get the icon module/resource names */
UNICODE_STRING ustrModule; UNICODE_STRING ustrModule;
UNICODE_STRING ustrRsrc; UNICODE_STRING ustrRsrc;
PVOID pvBuf;
HMODULE hModule; HMODULE hModule;
ustrModule.MaximumLength = MAX_PATH * sizeof(WCHAR); ustrModule.MaximumLength = 0;
ustrRsrc.MaximumLength = 256; ustrRsrc.MaximumLength = 0;
/* Get the buffer size */
if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
{
return NULL;
}
ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength); ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
if (!ustrModule.Buffer) if (!ustrModule.Buffer)
@ -1703,62 +1718,33 @@ CURSORICON_CopyImage(
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL; return NULL;
} }
/* Keep track of the buffer for the resource, NtUserGetIconInfo might overwrite it */
pvBuf = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength); if (ustrRsrc.MaximumLength)
if (!pvBuf) {
ustrRsrc.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
if (!ustrRsrc.Buffer)
{ {
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL; return NULL;
} }
ustrRsrc.Buffer = pvBuf; }
do
{
if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE)) if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
{ {
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
HeapFree(GetProcessHeap(), 0, pvBuf); if (!IS_INTRESOURCE(ustrRsrc.Buffer))
HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
return NULL; 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);
/* NULL-terminate our strings */ /* NULL-terminate our strings */
ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = 0; ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = UNICODE_NULL;
if (!IS_INTRESOURCE(ustrRsrc.Buffer)) 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 */ /* Get the module handle */
if (!GetModuleHandleExW(0, ustrModule.Buffer, &hModule)) 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 */ /* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
leave: leave:
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); 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); TRACE("Returning 0x%08x.\n", ret);