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.

587 lines
16 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <ole2.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include "wmium.h"
  9. #define OffsetToPtr(Base, Offset) ((PBYTE)((PBYTE)Base + Offset))
  10. //
  11. // The routines below were blantenly stolen without remorse from the ole
  12. // sources in \nt\private\ole32\com\class\compapi.cxx. They are copied here
  13. // so that WMI doesn't need to load in ole32 only to convert a guid string
  14. // into its binary representation.
  15. //
  16. //+-------------------------------------------------------------------------
  17. //
  18. // Function: HexStringToDword (private)
  19. //
  20. // Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
  21. // return value in Value; check for chDelim;
  22. //
  23. // Arguments: [lpsz] - the hex string to convert
  24. // [Value] - the returned value
  25. // [cDigits] - count of digits
  26. //
  27. // Returns: TRUE for success
  28. //
  29. //--------------------------------------------------------------------------
  30. BOOL HexStringToDword(LPCSTR lpsz, DWORD * RetValue,
  31. int cDigits, WCHAR chDelim)
  32. {
  33. int Count;
  34. DWORD Value;
  35. Value = 0;
  36. for (Count = 0; Count < cDigits; Count++, lpsz++)
  37. {
  38. if (*lpsz >= '0' && *lpsz <= '9')
  39. Value = (Value << 4) + *lpsz - '0';
  40. else if (*lpsz >= 'A' && *lpsz <= 'F')
  41. Value = (Value << 4) + *lpsz - 'A' + 10;
  42. else if (*lpsz >= 'a' && *lpsz <= 'f')
  43. Value = (Value << 4) + *lpsz - 'a' + 10;
  44. else
  45. return(FALSE);
  46. }
  47. *RetValue = Value;
  48. if (chDelim != 0)
  49. return *lpsz++ == chDelim;
  50. else
  51. return TRUE;
  52. }
  53. //+-------------------------------------------------------------------------
  54. //
  55. // Function: wUUIDFromString (internal)
  56. //
  57. // Synopsis: Parse UUID such as 00000000-0000-0000-0000-000000000000
  58. //
  59. // Arguments: [lpsz] - Supplies the UUID string to convert
  60. // [pguid] - Returns the GUID.
  61. //
  62. // Returns: TRUE if successful
  63. //
  64. //--------------------------------------------------------------------------
  65. BOOL wUUIDFromString(LPCSTR lpsz, LPGUID pguid)
  66. {
  67. DWORD dw;
  68. if (!HexStringToDword(lpsz, &pguid->Data1, sizeof(DWORD)*2, '-'))
  69. return FALSE;
  70. lpsz += sizeof(DWORD)*2 + 1;
  71. if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
  72. return FALSE;
  73. lpsz += sizeof(WORD)*2 + 1;
  74. pguid->Data2 = (WORD)dw;
  75. if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
  76. return FALSE;
  77. lpsz += sizeof(WORD)*2 + 1;
  78. pguid->Data3 = (WORD)dw;
  79. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  80. return FALSE;
  81. lpsz += sizeof(BYTE)*2;
  82. pguid->Data4[0] = (BYTE)dw;
  83. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, '-'))
  84. return FALSE;
  85. lpsz += sizeof(BYTE)*2+1;
  86. pguid->Data4[1] = (BYTE)dw;
  87. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  88. return FALSE;
  89. lpsz += sizeof(BYTE)*2;
  90. pguid->Data4[2] = (BYTE)dw;
  91. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  92. return FALSE;
  93. lpsz += sizeof(BYTE)*2;
  94. pguid->Data4[3] = (BYTE)dw;
  95. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  96. return FALSE;
  97. lpsz += sizeof(BYTE)*2;
  98. pguid->Data4[4] = (BYTE)dw;
  99. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  100. return FALSE;
  101. lpsz += sizeof(BYTE)*2;
  102. pguid->Data4[5] = (BYTE)dw;
  103. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  104. return FALSE;
  105. lpsz += sizeof(BYTE)*2;
  106. pguid->Data4[6] = (BYTE)dw;
  107. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  108. return FALSE;
  109. lpsz += sizeof(BYTE)*2;
  110. pguid->Data4[7] = (BYTE)dw;
  111. return TRUE;
  112. }
  113. //+-------------------------------------------------------------------------
  114. //
  115. // Function: wGUIDFromString (internal)
  116. //
  117. // Synopsis: Parse GUID such as {00000000-0000-0000-0000-000000000000}
  118. //
  119. // Arguments: [lpsz] - the guid string to convert
  120. // [pguid] - guid to return
  121. //
  122. // Returns: TRUE if successful
  123. //
  124. //--------------------------------------------------------------------------
  125. BOOL wGUIDFromString(LPCSTR lpsz, LPGUID pguid)
  126. {
  127. DWORD dw;
  128. if (*lpsz == '{' )
  129. lpsz++;
  130. if(wUUIDFromString(lpsz, pguid) != TRUE)
  131. return FALSE;
  132. lpsz +=36;
  133. if (*lpsz == '}' )
  134. lpsz++;
  135. if (*lpsz != '\0') // check for zero terminated string - test bug #18307
  136. {
  137. return FALSE;
  138. }
  139. return TRUE;
  140. }
  141. PTCHAR GuidToString(
  142. PTCHAR s,
  143. LPGUID piid
  144. )
  145. {
  146. wsprintf(s, TEXT("%x-%x-%x-%x%x%x%x%x%x%x%x"),
  147. piid->Data1, piid->Data2,
  148. piid->Data3,
  149. piid->Data4[0], piid->Data4[1],
  150. piid->Data4[2], piid->Data4[3],
  151. piid->Data4[4], piid->Data4[5],
  152. piid->Data4[6], piid->Data4[7]);
  153. return(s);
  154. }
  155. #if 0
  156. void WackOnFile(void)
  157. {
  158. ULONG Status;
  159. HANDLE FH;
  160. FH = CreateFile("e:\\foo.baz",
  161. GENERIC_READ,
  162. FILE_SHARE_READ,
  163. NULL,
  164. OPEN_EXISTING,
  165. FILE_ATTRIBUTE_NORMAL,
  166. NULL);
  167. if (FH != INVALID_HANDLE_VALUE)
  168. {
  169. Status = ERROR_SUCCESS;
  170. CloseHandle(FH);
  171. } else {
  172. Status = GetLastError();
  173. }
  174. printf("CreateFile --> %d\n", Status);
  175. }
  176. void CheckOwnPriv(
  177. void
  178. )
  179. {
  180. UCHAR Buffer[4096];
  181. HANDLE TokenHandle;
  182. ULONG SizeNeeded;
  183. BOOL b;
  184. ULONG i;
  185. PTOKEN_PRIVILEGES TokenPrivInfo;
  186. if (! ImpersonateSelf(SecurityImpersonation))
  187. {
  188. printf("Impersonatself -> %d\n", GetLastError());
  189. return;
  190. }
  191. b = OpenThreadToken(GetCurrentThread(),
  192. TOKEN_QUERY,
  193. TRUE,
  194. &TokenHandle);
  195. if (! b)
  196. {
  197. printf("OpenThreadToken failed %d\n", GetLastError());
  198. return;
  199. }
  200. printf("OpenThreadToken succeeded\n");
  201. TokenPrivInfo = (PTOKEN_PRIVILEGES)Buffer;
  202. b = GetTokenInformation(TokenHandle,
  203. TokenPrivileges,
  204. TokenPrivInfo,
  205. sizeof(Buffer),
  206. &SizeNeeded);
  207. printf("GetTokenInformation(YokenPriv) -> %s (%d), sizeNeeded = %d\n",
  208. b ? "TRUE" : "FALSE", GetLastError(),
  209. SizeNeeded);
  210. RevertToSelf();
  211. if (b)
  212. {
  213. printf("Priv count is %d\n", TokenPrivInfo->PrivilegeCount);
  214. for (i = 0; i < TokenPrivInfo->PrivilegeCount; i++)
  215. {
  216. UCHAR PrivName[1024];
  217. ULONG SizePrivName = sizeof(PrivName);
  218. if ( ! LookupPrivilegeName(NULL,
  219. &TokenPrivInfo->Privileges[i].Luid,
  220. PrivName,
  221. &SizePrivName))
  222. {
  223. sprintf(PrivName, "[Error %d]", GetLastError());
  224. }
  225. printf("Priv %s %x%x has attr %x\n",
  226. PrivName,
  227. TokenPrivInfo->Privileges[i].Luid.HighPart,
  228. TokenPrivInfo->Privileges[i].Luid.LowPart,
  229. TokenPrivInfo->Privileges[i].Attributes);
  230. }
  231. printf("\n");
  232. }
  233. }
  234. PCHAR SidUsage[] =
  235. {
  236. "SidTypeZero",
  237. "SidTypeUser",
  238. "SidTypeGroup",
  239. "SidTypeDomain",
  240. "SidTypeAlias",
  241. "SidTypeWellKnownGroup",
  242. "SidTypeDeletedAccount",
  243. "SidTypeInvalid",
  244. "SidTypeUnknown",
  245. "SidTypeComputer",
  246. };
  247. void GetCallerInfo(BOOLEAN Impersonating)
  248. {
  249. UCHAR Buffer[4096];
  250. PTOKEN_USER TokenUserInfo = (PTOKEN_USER)Buffer;
  251. PSID_AND_ATTRIBUTES SidAndAttributes = &TokenUserInfo->User;
  252. PSID Sid;
  253. HANDLE TokenHandle;
  254. ULONG SizeNeeded;
  255. BOOLEAN b;
  256. CHAR Name[MAX_PATH];
  257. CHAR Domain[MAX_PATH];
  258. ULONG NameSize = sizeof(Name);
  259. ULONG DomainSize = sizeof(Domain);
  260. SID_NAME_USE SidNameUse;
  261. ULONG i;
  262. PUCHAR SidBuffer;
  263. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  264. PTOKEN_PRIVILEGES TokenPrivInfo;
  265. SidBuffer = malloc(RtlLengthRequiredSid( 1 ));
  266. RtlInitializeSid( SidBuffer, &NtAuthority, 1);
  267. *(RtlSubAuthoritySid( SidBuffer, 0 )) = SECURITY_LOCAL_SYSTEM_RID;
  268. b = OpenThreadToken(GetCurrentThread(),
  269. TOKEN_QUERY,
  270. TRUE,
  271. &TokenHandle);
  272. if (! b)
  273. {
  274. printf("OpenThreadToken failed %d\n", GetLastError());
  275. return;
  276. }
  277. printf("OpenThreadToken succeeded\n");
  278. TokenPrivInfo = (PTOKEN_PRIVILEGES)Buffer;
  279. b = GetTokenInformation(TokenHandle,
  280. TokenPrivileges,
  281. TokenPrivInfo,
  282. sizeof(Buffer),
  283. &SizeNeeded);
  284. printf("GetTokenInformation(YokenPriv) -> %s (%d), sizeNeeded = %d\n",
  285. b ? "TRUE" : "FALSE", GetLastError(),
  286. SizeNeeded);
  287. if (b)
  288. {
  289. RpcRevertToSelf();
  290. printf("Priv count is %d\n", TokenPrivInfo->PrivilegeCount);
  291. for (i = 0; i < TokenPrivInfo->PrivilegeCount; i++)
  292. {
  293. UCHAR PrivName[1024];
  294. ULONG SizePrivName = sizeof(PrivName);
  295. if ( ! LookupPrivilegeName(NULL,
  296. &TokenPrivInfo->Privileges[i].Luid,
  297. PrivName,
  298. &SizePrivName))
  299. {
  300. sprintf(PrivName, "[Error %d]", GetLastError());
  301. }
  302. printf("Priv %s %x%x has attr %x\n",
  303. PrivName,
  304. TokenPrivInfo->Privileges[i].Luid.HighPart,
  305. TokenPrivInfo->Privileges[i].Luid.LowPart,
  306. TokenPrivInfo->Privileges[i].Attributes);
  307. }
  308. printf("\n");
  309. RpcImpersonateClient(0);
  310. }
  311. b = GetTokenInformation(TokenHandle,
  312. TokenUser,
  313. TokenUserInfo,
  314. sizeof(Buffer),
  315. &SizeNeeded);
  316. printf("GetTokenInformation -> %s (%d), sizeNeeded = %d\n",
  317. b ? "TRUE" : "FALSE", GetLastError(),
  318. SizeNeeded);
  319. if (b)
  320. {
  321. if (Impersonating)
  322. {
  323. RpcRevertToSelf();
  324. }
  325. Sid = SidAndAttributes->Sid;
  326. if (EqualSid(Sid, (PSID)SidBuffer) && GetLastError() == ERROR_SUCCESS)
  327. {
  328. printf("Called by LocalSystem !!\n");
  329. } else {
  330. printf("EqualSid %d\n", GetLastError());
  331. }
  332. b = LookupAccountSid(NULL,
  333. Sid,
  334. Name,
  335. &NameSize,
  336. Domain,
  337. &DomainSize,
  338. &SidNameUse);
  339. if (Impersonating)
  340. {
  341. RpcImpersonateClient(0);
  342. }
  343. if (b)
  344. {
  345. printf("Account: %s\\%s Type %s\n", Domain, Name, SidUsage[SidNameUse]);
  346. } else {
  347. printf("LookupAccountSid %d\n", GetLastError());
  348. }
  349. }
  350. CloseHandle(TokenHandle);
  351. }
  352. #endif
  353. void EventCallbackRoutine(PWNODE_HEADER WnodeHeader, ULONG Context);
  354. #define DATA_PROVIDER_PNPID_GUID \
  355. { 0xc7bf35d2,0xaadb,0x11d1, { 0xbf,0x4a,0x00,0xa0,0xc9,0x06,0x29,0x10 } }
  356. GUID GuidXYZ = DATA_PROVIDER_PNPID_GUID;
  357. ULONG EventsReceived;
  358. void EventCallbackRoutine(PWNODE_HEADER WnodeHeader, ULONG Context)
  359. {
  360. PWNODE_SINGLE_INSTANCE WnodeSI = (PWNODE_SINGLE_INSTANCE)WnodeHeader;
  361. PWNODE_HEADER Wnode = WnodeHeader;
  362. LPGUID EventGuid = &WnodeHeader->Guid;
  363. CHAR s[MAX_PATH];
  364. ULONG Status;
  365. WMIHANDLE Handle;
  366. #if 0
  367. GetCallerInfo(FALSE);
  368. RevertToSelf();
  369. GetCallerInfo(FALSE);
  370. WackOnFile();
  371. Status = RpcImpersonateClient(0);
  372. printf("RpcImpersonateClient -> %d\n", Status);
  373. if (Status == ERROR_SUCCESS)
  374. {
  375. WmiOpenBlock(&GuidXYZ, GENERIC_READ, &Handle);
  376. GetCallerInfo(TRUE);
  377. WackOnFile();
  378. RpcRevertToSelf();
  379. }
  380. #endif
  381. EventsReceived++;
  382. printf("Receieved event for guid %s\n", GuidToString(s, EventGuid));
  383. printf("BufferSize = 0x%x\n", Wnode->BufferSize);
  384. printf("ProviderId = %x\n", Wnode->ProviderId); // Provider Id of driver returning this buffer
  385. printf("Version = %x\n", Wnode->Version); // Reserved
  386. printf("Linkage = %x\n", Wnode->Linkage); // Linkage field reserved for WMI
  387. printf("ClientContext = %x\n", Wnode->ClientContext);
  388. printf("Flags = %x\n", Wnode->Flags); // Flags, see below
  389. if (Wnode->Flags & WNODE_FLAG_SINGLE_INSTANCE)
  390. {
  391. printf("WNODE_SINGLE_INSTANCE\n");
  392. printf("OffsetInstanceName = %x\n", WnodeSI->OffsetInstanceName);
  393. printf("InstanceIndex = %x\n", WnodeSI->InstanceIndex); // (Static Instance Names)
  394. printf("DataBlockOffset = %x\n", WnodeSI->DataBlockOffset); // offset from beginning of WNODE to data block
  395. printf("SizeDataBlock = %x\n", WnodeSI->SizeDataBlock); // Size of data block for instance
  396. }
  397. printf("\n%d events received\n", EventsReceived);
  398. }
  399. #if 0
  400. #define WmiRpcProtocolSequence1 TEXT("ncacn_np")
  401. #define WmiRpcProtocolSequence2 TEXT("ncalrpc")
  402. #define MaxRpcCalls RPC_C_PROTSEQ_MAX_REQS_DEFAULT
  403. void
  404. CreateEndpoints(void)
  405. {
  406. ULONG i;
  407. ULONG Status;
  408. CHAR UniqueEndpoint[MAX_PATH];
  409. SECURITY_DESCRIPTOR SD;
  410. InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION);
  411. SetSecurityDescriptorDacl(&SD, TRUE, NULL, FALSE);
  412. for (i = 0; i < 20; i++)
  413. {
  414. sprintf(UniqueEndpoint, "TESTLRPCEP_%x", i);
  415. Status = RpcServerUseProtseqEp(WmiRpcProtocolSequence2,
  416. MaxRpcCalls,
  417. UniqueEndpoint,
  418. &SD); // Security descriptor
  419. if (Status != ERROR_SUCCESS)
  420. {
  421. printf("RpcServerUseProtseqEp failed %d\n", Status);
  422. }
  423. }
  424. for (i = 0; i < 20; i++)
  425. {
  426. sprintf(UniqueEndpoint, "\\pipe\\TESTEP_%x", i);
  427. Status = RpcServerUseProtseqEp(WmiRpcProtocolSequence1,
  428. MaxRpcCalls,
  429. UniqueEndpoint,
  430. &SD); // Security descriptor
  431. if (Status != ERROR_SUCCESS)
  432. {
  433. printf("RpcServerUseProtseqEp failed %d\n", Status);
  434. }
  435. }
  436. }
  437. #endif
  438. PWNODE_HEADER EventPtrBuffer;
  439. int _cdecl main(int argc, char *argv[])
  440. {
  441. ULONG Status;
  442. GUID Guid;
  443. ULONG c,i;
  444. #if 0
  445. c = 1;
  446. for (i = 0; i < 101; i++)
  447. {
  448. c += i;
  449. }
  450. printf("c = %d\n",c);
  451. #endif
  452. if ((argc != 2) && (argc != 3))
  453. {
  454. printf("getevent <guid>\n");
  455. return(0);
  456. }
  457. #if 0
  458. CheckOwnPriv();
  459. if (argc == 3)
  460. {
  461. printf("Creating endpoints\n");
  462. CreateEndpoints();
  463. }
  464. #endif
  465. //
  466. // Parse the guid parameter
  467. if (! wGUIDFromString(argv[1], &Guid))
  468. {
  469. printf("Bad guid %s\n", argv[1]);
  470. return(0);
  471. }
  472. Status = WmiNotificationRegistration(&Guid,
  473. TRUE,
  474. EventCallbackRoutine,
  475. 0,
  476. NOTIFICATION_CALLBACK_DIRECT);
  477. if (Status != ERROR_SUCCESS)
  478. {
  479. printf("WMINotificationRegistration %d\n", Status);
  480. return(1);
  481. }
  482. // Loop forever receiving events
  483. while (1) Sleep(1000*1000);
  484. return(ERROR_SUCCESS);
  485. }