Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

439 lines
11 KiB

  1. //*************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation 1998
  4. // All rights reserved
  5. //
  6. // util.cxx
  7. //
  8. //*************************************************************
  9. #include "common.hxx"
  10. MSGWAITFORMULTIPLEOBJECTS * pfnMsgWaitForMultipleObjects = 0;
  11. PEEKMESSAGEW * pfnPeekMessageW = 0;
  12. TRANSLATEMESSAGE * pfnTranslateMessage = 0;
  13. DISPATCHMESSAGEW * pfnDispatchMessageW = 0;
  14. GETPROCESSWINDOWSTATION * pfnGetProcessWindowStation = 0;
  15. CLOSEWINDOWSTATION * pfnCloseWindowStation = 0;
  16. GETUSEROBJECTINFORMATIONW * pfnGetUserObjectInformationW = 0;
  17. MSISETINTERNALUI * gpfnMsiSetInternalUI = 0;
  18. MSICONFIGUREPRODUCTEXW * gpfnMsiConfigureProductEx = 0;
  19. MSIPROVIDECOMPONENTFROMDESCRIPTORW * gpfnMsiProvideComponentFromDescriptor = 0;
  20. MSIDECOMPOSEDESCRIPTORW * gpfnMsiDecomposeDescriptor = 0;
  21. MSIGETPRODUCTINFOW * gpfnMsiGetProductInfo = 0;
  22. MSIADVERTISESCRIPTW * gpfnMsiAdvertiseScript = 0;
  23. MSIQUERYPRODUCTSTATEW * gpfnMsiQueryProductState = 0;
  24. MSIISPRODUCTELEVATEDW * gpfnMsiIsProductElevated = 0;
  25. MSIREINSTALLPRODUCTW * gpfnMsiReinstallProduct = 0;
  26. void
  27. FreeApplicationInfo(
  28. APPLICATION_INFO * ApplicationInfo
  29. )
  30. {
  31. if ( ! ApplicationInfo )
  32. return;
  33. LocalFree( ApplicationInfo->pwszDeploymentId );
  34. LocalFree( ApplicationInfo->pwszDeploymentName );
  35. LocalFree( ApplicationInfo->pwszGPOName );
  36. LocalFree( ApplicationInfo->pwszProductCode );
  37. LocalFree( ApplicationInfo->pwszDescriptor );
  38. LocalFree( ApplicationInfo->pwszSetupCommand );
  39. }
  40. PSID
  41. AppmgmtGetUserSid(
  42. HANDLE hUserToken // = 0
  43. )
  44. {
  45. PSID pSid;
  46. HANDLE hToken;
  47. PTOKEN_USER pTokenUserData;
  48. UCHAR Buffer[sizeof(TOKEN_USER) + sizeof(SID) + ((SID_MAX_SUB_AUTHORITIES-1) * sizeof(ULONG))];
  49. DWORD Size;
  50. DWORD Status;
  51. BOOL bStatus;
  52. if ( ! hUserToken )
  53. {
  54. bStatus = OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken );
  55. if ( ! bStatus )
  56. bStatus = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken );
  57. if ( ! bStatus )
  58. return NULL;
  59. }
  60. else
  61. {
  62. hToken = hUserToken;
  63. }
  64. Size = sizeof(Buffer);
  65. pTokenUserData = (PTOKEN_USER) Buffer;
  66. bStatus = GetTokenInformation(
  67. hToken,
  68. TokenUser,
  69. pTokenUserData,
  70. Size,
  71. &Size );
  72. if ( ! hUserToken )
  73. CloseHandle( hToken );
  74. if ( ! bStatus )
  75. return NULL;
  76. Size = GetLengthSid( pTokenUserData->User.Sid );
  77. pSid = (PSID) LocalAlloc( 0, Size );
  78. if ( pSid )
  79. {
  80. bStatus = CopySid( Size, pSid, pTokenUserData->User.Sid );
  81. if ( ! bStatus )
  82. {
  83. LocalFree( pSid );
  84. pSid = NULL;
  85. }
  86. }
  87. return pSid;
  88. }
  89. void
  90. DwordToString(
  91. DWORD Number,
  92. WCHAR * wszNumber
  93. )
  94. {
  95. WCHAR * pwszString;
  96. WCHAR c;
  97. DWORD Length;
  98. DWORD n;
  99. pwszString = wszNumber;
  100. Length = 0;
  101. do
  102. {
  103. *pwszString++ = (WCHAR) (L'0' + Number % 10);
  104. Number /= 10;
  105. Length++;
  106. } while ( Number );
  107. *pwszString = 0;
  108. for ( n = 0; n < Length / 2; n++ )
  109. {
  110. c = wszNumber[n];
  111. wszNumber[n] = wszNumber[Length-n-1];
  112. wszNumber[Length-n-1] = c;
  113. }
  114. }
  115. BOOL
  116. LoadUser32Funcs()
  117. {
  118. HINSTANCE hUser32 = 0;
  119. if ( pfnMsgWaitForMultipleObjects && pfnPeekMessageW && pfnTranslateMessage && pfnDispatchMessageW &&
  120. pfnGetProcessWindowStation && pfnCloseWindowStation && pfnGetUserObjectInformationW )
  121. return TRUE;
  122. hUser32 = LoadLibrary( L"user32.dll" );
  123. if ( ! hUser32 )
  124. return FALSE;
  125. pfnMsgWaitForMultipleObjects = (MSGWAITFORMULTIPLEOBJECTS *) GetProcAddress( hUser32, "MsgWaitForMultipleObjects" );
  126. pfnPeekMessageW = (PEEKMESSAGEW *) GetProcAddress( hUser32, "PeekMessageW" );
  127. pfnTranslateMessage = (TRANSLATEMESSAGE *) GetProcAddress( hUser32, "TranslateMessage" );
  128. pfnDispatchMessageW = (DISPATCHMESSAGEW *) GetProcAddress( hUser32, "DispatchMessageW" );
  129. pfnGetProcessWindowStation = (GETPROCESSWINDOWSTATION *) GetProcAddress( hUser32, "GetProcessWindowStation" );
  130. pfnCloseWindowStation = (CLOSEWINDOWSTATION *) GetProcAddress( hUser32, "CloseWindowStation" );
  131. pfnGetUserObjectInformationW = (GETUSEROBJECTINFORMATIONW *) GetProcAddress( hUser32, "GetUserObjectInformationW" );
  132. if ( ! pfnMsgWaitForMultipleObjects || ! pfnPeekMessageW || ! pfnTranslateMessage || ! pfnDispatchMessageW ||
  133. ! pfnGetProcessWindowStation || ! pfnCloseWindowStation || ! pfnGetUserObjectInformationW )
  134. {
  135. FreeLibrary( hUser32 );
  136. return FALSE;
  137. }
  138. // user32 remains loaded
  139. return TRUE;
  140. }
  141. BOOL
  142. LoadLoadString()
  143. {
  144. HINSTANCE hUser32 = 0;
  145. if ( pfnLoadStringW )
  146. return TRUE;
  147. hUser32 = LoadLibrary( L"user32.dll" );
  148. if ( ! hUser32 )
  149. return FALSE;
  150. pfnLoadStringW = (LOADSTRINGW *) GetProcAddress( hUser32, "LoadStringW" );
  151. if ( ! pfnLoadStringW )
  152. {
  153. FreeLibrary( hUser32 );
  154. return FALSE;
  155. }
  156. // user32 remains loaded
  157. return TRUE;
  158. }
  159. void
  160. GuidToString(
  161. GUID & Guid,
  162. PWCHAR pwszGuid
  163. )
  164. {
  165. *pwszGuid = 0;
  166. StringCchPrintf(
  167. pwszGuid,
  168. 40,
  169. L"{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
  170. Guid.Data1,
  171. Guid.Data2,
  172. Guid.Data3,
  173. Guid.Data4[0],
  174. Guid.Data4[1],
  175. Guid.Data4[2],
  176. Guid.Data4[3],
  177. Guid.Data4[4],
  178. Guid.Data4[5],
  179. Guid.Data4[6],
  180. Guid.Data4[7]
  181. );
  182. }
  183. void
  184. GuidToString(
  185. GUID & Guid,
  186. PWCHAR *ppwszGuid
  187. )
  188. {
  189. *ppwszGuid = new WCHAR[40];
  190. if ( *ppwszGuid )
  191. GuidToString( Guid, *ppwszGuid);
  192. }
  193. void
  194. StringToGuid(
  195. PWCHAR pwszGuid,
  196. GUID * pGuid
  197. )
  198. {
  199. UNICODE_STRING String;
  200. DWORD Data;
  201. // mimicking scanf of L"{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"
  202. if (lstrlen(pwszGuid) != GUID_LENGTH)
  203. {
  204. memset(pGuid, 0, sizeof(GUID));
  205. return;
  206. }
  207. String.Buffer = pwszGuid + 1;
  208. String.Length = String.MaximumLength = 16;
  209. RtlUnicodeStringToInteger( &String, 16, &pGuid->Data1 );
  210. String.Buffer += 9;
  211. String.Length = String.MaximumLength = 8;
  212. RtlUnicodeStringToInteger( &String, 16, &Data );
  213. pGuid->Data2 = (USHORT) Data;
  214. String.Buffer += 5;
  215. RtlUnicodeStringToInteger( &String, 16, &Data );
  216. pGuid->Data3 = (USHORT) Data;
  217. String.Buffer += 5;
  218. String.Length = String.MaximumLength = 4;
  219. for ( DWORD n = 0; n <= 7; n++ )
  220. {
  221. RtlUnicodeStringToInteger( &String, 16, &Data );
  222. pGuid->Data4[n] = (UCHAR) Data;
  223. String.Buffer += 2;
  224. if ( 1 == n )
  225. String.Buffer++;
  226. }
  227. }
  228. HRESULT
  229. CreateGuid(GUID *pGuid)
  230. {
  231. int err;
  232. // We simply use the RPC system supplied API
  233. if ((err = UuidCreate(pGuid)) != RPC_S_UUID_LOCAL_ONLY)
  234. {
  235. return err ? HRESULT_FROM_WIN32(err) : S_OK;
  236. }
  237. return S_OK;
  238. }
  239. DWORD
  240. ReadStringValue(
  241. HKEY hKey,
  242. WCHAR * pwszValueName,
  243. WCHAR ** ppwszValue
  244. )
  245. {
  246. DWORD Status;
  247. DWORD Size;
  248. *ppwszValue = 0;
  249. Size = 0;
  250. Status = RegQueryValueEx(
  251. hKey,
  252. pwszValueName,
  253. 0,
  254. NULL,
  255. (LPBYTE) *ppwszValue,
  256. &Size );
  257. //
  258. // Does not return ERROR_MORE_DATA when buffer is NULL.
  259. //
  260. if ( Status != ERROR_SUCCESS )
  261. return Status;
  262. *ppwszValue = new WCHAR[Size / 2];
  263. if ( ! *ppwszValue )
  264. return ERROR_OUTOFMEMORY;
  265. Status = RegQueryValueEx(
  266. hKey,
  267. pwszValueName,
  268. 0,
  269. NULL,
  270. (LPBYTE) *ppwszValue,
  271. &Size );
  272. if ( Status != ERROR_SUCCESS )
  273. {
  274. delete *ppwszValue;
  275. *ppwszValue = 0;
  276. }
  277. return Status;
  278. }
  279. DWORD
  280. GetSidString(
  281. HANDLE hToken,
  282. UNICODE_STRING* pSidString
  283. )
  284. {
  285. LONG Status;
  286. BOOL bStatus;
  287. DWORD Size;
  288. UCHAR Buffer[sizeof(TOKEN_USER) + sizeof(SID) + ((SID_MAX_SUB_AUTHORITIES-1) * sizeof(ULONG))];
  289. PTOKEN_USER pTokenUser;
  290. Status = ERROR_SUCCESS;
  291. Size = sizeof(Buffer);
  292. pTokenUser = (PTOKEN_USER) Buffer;
  293. bStatus = GetTokenInformation(
  294. hToken,
  295. TokenUser,
  296. pTokenUser,
  297. Size,
  298. &Size );
  299. if ( ! bStatus )
  300. Status = GetLastError();
  301. if ( ERROR_SUCCESS == Status )
  302. {
  303. Status = RtlConvertSidToUnicodeString(
  304. pSidString,
  305. pTokenUser->User.Sid,
  306. TRUE );
  307. if ( ! NT_SUCCESS( Status ) )
  308. {
  309. Status = RtlNtStatusToDosError( Status );
  310. }
  311. }
  312. return Status;
  313. }
  314. CLoadMsi::CLoadMsi( DWORD &Status )
  315. {
  316. hMsi = LoadLibrary( L"msi.dll" );
  317. if ( ! hMsi )
  318. {
  319. Status = GetLastError();
  320. return;
  321. }
  322. gpfnMsiSetInternalUI = (MSISETINTERNALUI *) GetProcAddress( hMsi, "MsiSetInternalUI" );
  323. gpfnMsiConfigureProductEx = (MSICONFIGUREPRODUCTEXW *) GetProcAddress( hMsi, "MsiConfigureProductExW" );
  324. gpfnMsiProvideComponentFromDescriptor = (MSIPROVIDECOMPONENTFROMDESCRIPTORW *) GetProcAddress( hMsi, "MsiProvideComponentFromDescriptorW" );
  325. gpfnMsiDecomposeDescriptor = (MSIDECOMPOSEDESCRIPTORW *) GetProcAddress( hMsi, "MsiDecomposeDescriptorW" );
  326. gpfnMsiGetProductInfo = (MSIGETPRODUCTINFOW *) GetProcAddress( hMsi, "MsiGetProductInfoW" );
  327. gpfnMsiAdvertiseScript = (MSIADVERTISESCRIPTW *) GetProcAddress( hMsi, "MsiAdvertiseScriptW" );
  328. gpfnMsiQueryProductState = (MSIQUERYPRODUCTSTATEW *) GetProcAddress( hMsi, "MsiQueryProductStateW" );
  329. gpfnMsiIsProductElevated = (MSIISPRODUCTELEVATEDW *) GetProcAddress( hMsi, "MsiIsProductElevatedW" );
  330. gpfnMsiReinstallProduct = (MSIREINSTALLPRODUCTW *) GetProcAddress( hMsi, "MsiReinstallProductW" );
  331. if ( ! gpfnMsiSetInternalUI ||
  332. ! gpfnMsiConfigureProductEx ||
  333. ! gpfnMsiProvideComponentFromDescriptor ||
  334. ! gpfnMsiDecomposeDescriptor ||
  335. ! gpfnMsiAdvertiseScript ||
  336. ! gpfnMsiQueryProductState ||
  337. ! gpfnMsiIsProductElevated ||
  338. ! gpfnMsiReinstallProduct )
  339. {
  340. Status = ERROR_PROC_NOT_FOUND;
  341. return;
  342. }
  343. Status = ERROR_SUCCESS;
  344. }
  345. CLoadMsi::~CLoadMsi()
  346. {
  347. if ( hMsi )
  348. FreeLibrary( hMsi );
  349. }