mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
* Sync up to trunk head (r64939).
svn path=/branches/shell-experiments/; revision=64941
This commit is contained in:
commit
8039ce5b7d
27 changed files with 1252 additions and 860 deletions
|
@ -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)
|
||||||
|
|
||||||
|
|
348
base/applications/network/net/cmdUser.c
Normal file
348
base/applications/network/net/cmdUser.c
Normal 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 */
|
|
@ -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..."
|
||||||
|
|
|
@ -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..."
|
||||||
|
|
|
@ -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..."
|
||||||
|
|
|
@ -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}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
...)
|
...)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue