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.

671 lines
14 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. lsautil.cxx
  6. Abstract:
  7. Lsa Utility functions
  8. Author:
  9. Larry Zhu (Lzhu) May 1, 2001
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #pragma hdrstop
  14. namespace LSA_NS {
  15. /*++
  16. Title:
  17. StripPathFromFileName
  18. Routine Description:
  19. Function used stip the path component from a fully
  20. qualified file name.
  21. Arguments:
  22. pszFile - pointer to full file name.
  23. Return Value:
  24. Pointer to start of file name in path.
  25. --*/
  26. LPCTSTR
  27. StripPathFromFileName(
  28. IN LPCTSTR pszFile
  29. )
  30. {
  31. LPCTSTR pszFileName;
  32. if (pszFile)
  33. {
  34. pszFileName = _tcsrchr( pszFile, _T('\\') );
  35. if (pszFileName)
  36. {
  37. pszFileName++;
  38. }
  39. else
  40. {
  41. pszFileName = pszFile;
  42. }
  43. }
  44. else
  45. {
  46. pszFileName = kstrEmpty;
  47. }
  48. return pszFileName;
  49. }
  50. /////////////////////////////////////////////////////////////////////
  51. ULONG
  52. GetStructFieldVerbose(
  53. IN ULONG64 addrStructBase,
  54. IN PCSTR pszStructTypeName,
  55. IN PCSTR pszStructFieldName,
  56. IN ULONG BufferSize,
  57. OUT PVOID Buffer)
  58. {
  59. ULONG FieldOffset;
  60. ULONG ErrorCode;
  61. BOOL Success;
  62. Success = FALSE;
  63. //
  64. // Get the field offset
  65. //
  66. ErrorCode = GetFieldOffset(pszStructTypeName, pszStructFieldName, &FieldOffset );
  67. if (ErrorCode == NO_ERROR) {
  68. //
  69. // Read the data
  70. //
  71. Success = ReadMemory(addrStructBase + FieldOffset, Buffer, BufferSize, NULL);
  72. if (Success != TRUE) {
  73. DBG_LOG(LSA_ERROR, ("Cannot read structure field value at 0x%p, error %u\n", addrStructBase + FieldOffset, ErrorCode));
  74. return MEMORY_READ_ERROR;
  75. }
  76. } else {
  77. DBG_LOG(LSA_ERROR, ("Cannot get field offset of %s in %s, error %u\n", EasyStr(pszStructFieldName), EasyStr(pszStructTypeName), ErrorCode));
  78. return ErrorCode;
  79. }
  80. return 0; // 0 on success
  81. }
  82. /////////////////////////////////////////////////////////////////////
  83. ULONG
  84. GetStructPtrFieldVerbose(
  85. IN ULONG64 addrStructBase,
  86. IN PCSTR pszStructTypeName,
  87. IN PCSTR pszStructFieldName,
  88. IN PULONG64 Buffer)
  89. {
  90. ULONG FieldOffset = 0;
  91. ULONG ErrorCode = 0;
  92. //
  93. // Get the field offset inside the structure
  94. //
  95. ErrorCode = GetFieldOffset(pszStructTypeName, pszStructFieldName, &FieldOffset);
  96. if (ErrorCode == NO_ERROR) {
  97. //
  98. // Read the data
  99. //
  100. ErrorCode = GetPtrWithVoidStar(addrStructBase + FieldOffset, Buffer);
  101. if (ErrorCode != S_OK) {
  102. DBG_LOG(LSA_ERROR, ("Cannot read structure field value at 0x%p, error %u\n", addrStructBase + FieldOffset, ErrorCode));
  103. }
  104. } else {
  105. DBG_LOG(LSA_ERROR, ("Cannot get field offset of %s in structure %s, error %u\n", EasyStr(pszStructFieldName), EasyStr(pszStructTypeName), ErrorCode));
  106. }
  107. return ErrorCode;
  108. }
  109. //
  110. // This function is stolen from !process
  111. //
  112. HRESULT
  113. GetCurrentProcessor(
  114. IN PDEBUG_CLIENT Client,
  115. OPTIONAL OUT PULONG pProcessor,
  116. OPTIONAL OUT PHANDLE phCurrentThread
  117. )
  118. {
  119. HRESULT hr = E_INVALIDARG;
  120. PDEBUG_SYSTEM_OBJECTS DebugSystem;
  121. ULONG64 hCurrentThread;
  122. if (phCurrentThread != NULL) *phCurrentThread = NULL;
  123. if (pProcessor != NULL) *pProcessor = 0;
  124. if (Client == NULL ||
  125. (hr = Client->QueryInterface(__uuidof(IDebugSystemObjects),
  126. (void **)&DebugSystem)) != S_OK)
  127. {
  128. return hr;
  129. }
  130. hr = DebugSystem->GetCurrentThreadHandle(&hCurrentThread);
  131. if (hr == S_OK)
  132. {
  133. if (phCurrentThread != NULL)
  134. {
  135. *phCurrentThread = (HANDLE) hCurrentThread;
  136. }
  137. if (pProcessor != NULL)
  138. {
  139. *pProcessor = (ULONG) hCurrentThread - 1;
  140. }
  141. }
  142. DebugSystem->Release();
  143. return hr;
  144. }
  145. void LocalPrintGuid(IN const GUID *pGuid)
  146. {
  147. UNICODE_STRING GuidString = {0};
  148. NTSTATUS Status;
  149. if (pGuid) {
  150. Status = RtlStringFromGUID(*pGuid, &GuidString);
  151. if (NT_SUCCESS(Status))
  152. {
  153. dprintf("%wZ", &GuidString);
  154. }
  155. else
  156. {
  157. dprintf( "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  158. pGuid->Data1, pGuid->Data2, pGuid->Data3, pGuid->Data4[0],
  159. pGuid->Data4[1], pGuid->Data4[2], pGuid->Data4[3], pGuid->Data4[4],
  160. pGuid->Data4[5], pGuid->Data4[6], pGuid->Data4[7] );
  161. }
  162. }
  163. if (GuidString.Buffer)
  164. {
  165. RtlFreeUnicodeString(&GuidString);
  166. }
  167. }
  168. BOOL IsAddressInNonePAEKernelAddressSpace(IN ULONG64 addr)
  169. {
  170. static BOOL bIsPtr64 = IsPtr64WithVoidStar();
  171. if (!bIsPtr64) {
  172. return static_cast<LONG>(addr) < 0;
  173. } else {
  174. return static_cast<LONG64>(addr) < 0;
  175. }
  176. }
  177. /*++
  178. Routine Name:
  179. HResultFromWin32
  180. Routine Description:
  181. Returns the last error as an HRESULT assuming a failure.
  182. Arguments:
  183. dwError - Win32 error code
  184. Return Value:
  185. An HRESULT
  186. --*/
  187. HRESULT HResultFromWin32(IN DWORD dwError)
  188. {
  189. return HRESULT_FROM_WIN32(dwError);
  190. }
  191. /*++
  192. Routine Name:
  193. GetLastErrorAsHResult
  194. Routine Description:
  195. Returns the last error as an HRESULT assuming a failure.
  196. Arguments:
  197. None
  198. Return Value:
  199. An HRESULT.
  200. --*/
  201. HRESULT GetLastErrorAsHResult(void)
  202. {
  203. return HResultFromWin32(GetLastError());
  204. }
  205. NTSTATUS NtStatusFromWin32(IN DWORD dwError)
  206. {
  207. return (STATUS_SEVERITY_ERROR << 30) | (FACILITY_DEBUGGER << 16) | dwError;
  208. }
  209. NTSTATUS GetLastErrorAsNtStatus(void)
  210. {
  211. return NtStatusFromWin32(GetLastError());
  212. }
  213. BOOLEAN IsEmpty(IN PCSTR pszArgs)
  214. {
  215. if (!pszArgs) {
  216. return FALSE;
  217. }
  218. for (; *pszArgs; pszArgs++) {
  219. if (!isspace(*pszArgs)) {
  220. return FALSE;
  221. }
  222. }
  223. return TRUE;
  224. }
  225. void debugPrintHandle(IN HANDLE handle)
  226. {
  227. ULONG64 addrHandle = reinterpret_cast<ULONG_PTR>(handle);
  228. dprintf("%s", PtrToStr(addrHandle));
  229. }
  230. void PrintMessages(
  231. IN PCSTR pszMsg, OPTIONAL
  232. IN PCSTR pszSymHint OPTIONAL
  233. )
  234. {
  235. if (pszMsg || pszSymHint) {
  236. dprintf(kstrNewLine);
  237. }
  238. if (pszMsg) {
  239. dprintf(kstrStrLn, pszMsg);
  240. }
  241. if (pszSymHint) {
  242. dprintf(kstrCheckSym, pszSymHint);
  243. }
  244. }
  245. void handleLsaException(
  246. IN ELsaExceptionCode eExceptionCode,
  247. IN PCSTR pszMsg, OPTIONAL
  248. IN PCSTR pszSymHint OPTIONAL
  249. )
  250. {
  251. switch (eExceptionCode) {
  252. case kIncorrectSymbols:
  253. DBG_LOG(LSA_ERROR, ("\n%s", kstrIncorrectSymbols));
  254. PrintMessages(pszMsg, pszSymHint);
  255. break;
  256. case kExitOnControlC:
  257. DBG_LOG(LSA_LOG, (kstrStrLn, kstrExitOnControlC));
  258. dprintf(kstrNewLine);
  259. dprintf(kstrStrLn, kstrExitOnControlC);
  260. break;
  261. case kInvalid:
  262. default:
  263. DBG_LOG(LSA_ERROR, ("Invalid LSA exception code\n"));
  264. PrintMessages(pszMsg, pszSymHint);
  265. break;
  266. }
  267. }
  268. BOOL IsPtr64WithVoidStar(void)
  269. {
  270. static ULONG cbPtrSize = GetTypeSize(kstrVoidStar);
  271. return sizeof(ULONG64) == cbPtrSize;
  272. }
  273. PCSTR
  274. ReadStructStrField(
  275. IN ULONG64 addrStructBase,
  276. IN PCSTR pszStructTypeName,
  277. IN PCSTR pszStructStringFieldName)
  278. {
  279. ULONG fieldOffset = 0;
  280. fieldOffset = ReadFieldOffset(pszStructTypeName, pszStructStringFieldName);
  281. return TSTRING(addrStructBase + fieldOffset).toStrDirect();
  282. }
  283. PCWSTR
  284. ReadStructWStrField(
  285. IN ULONG64 addrStructBase,
  286. IN PCSTR pszStructTypeName,
  287. IN PCSTR pszStructWStringFieldName)
  288. {
  289. ULONG fieldOffset = 0;
  290. fieldOffset = ReadFieldOffset(pszStructTypeName, pszStructWStringFieldName);
  291. return TSTRING(addrStructBase + fieldOffset).toWStrDirect();
  292. }
  293. HRESULT ProcessKnownOptions(IN PCSTR pszArgs OPTIONAL)
  294. {
  295. HRESULT hRetval = S_OK;
  296. for (; SUCCEEDED(hRetval) && (pszArgs && *pszArgs); pszArgs++) {
  297. if (*pszArgs == '-' || *pszArgs == '/') {
  298. switch (*++pszArgs) {
  299. case '?':
  300. hRetval = E_INVALIDARG;
  301. break;
  302. default:
  303. break;
  304. }
  305. }
  306. }
  307. return hRetval;
  308. }
  309. HRESULT ProcessHelpRequest(IN PCSTR pszArgs OPTIONAL)
  310. {
  311. HRESULT hRetval = S_OK;
  312. for (; SUCCEEDED(hRetval) && (pszArgs && *pszArgs); pszArgs++) {
  313. if (*pszArgs == '-' || *pszArgs == '/') {
  314. switch (*++pszArgs) {
  315. case '?':
  316. hRetval = E_INVALIDARG;
  317. break;
  318. default:
  319. break;
  320. }
  321. }
  322. }
  323. return hRetval;
  324. }
  325. HRESULT GetFileNamePart(IN PCSTR pszFullPath, OUT PCSTR *ppszFileName)
  326. {
  327. HRESULT hRetval = E_FAIL;
  328. CHAR szfname[_MAX_FNAME] = {0};
  329. hRetval = pszFullPath && ppszFileName ? S_OK : E_INVALIDARG;
  330. if (SUCCEEDED(hRetval)) {
  331. _splitpath(pszFullPath, NULL, NULL, szfname, NULL);
  332. *ppszFileName = strstr(pszFullPath, szfname);
  333. }
  334. return hRetval;
  335. }
  336. CHAR toChar(IN CHAR c)
  337. {
  338. if (isprint(c)) {
  339. return c;
  340. }
  341. return '.';
  342. }
  343. void spaceIt(IN CHAR* buf, IN ULONG len)
  344. {
  345. memset(buf, ' ', len);
  346. }
  347. CHAR toHex(IN ULONG c)
  348. {
  349. static PCSTR pszDigits = "0123456789abcdef";
  350. static ULONG len = strlen(pszDigits);
  351. if (c <= len) { // c >= 0
  352. return pszDigits[c];
  353. }
  354. return '*';
  355. }
  356. void debugPrintHex(IN const void* buffer, IN ULONG cbBuffer)
  357. {
  358. const UCHAR* p = reinterpret_cast<const UCHAR*>(buffer);
  359. CHAR tmp[16] = {0};
  360. ULONG high = 0;
  361. ULONG low = 0;
  362. CHAR line[256] = {0};
  363. ULONG i = 0;
  364. if (!cbBuffer) return;
  365. spaceIt(line, 72);
  366. for (i = 0; i < cbBuffer; i++) {
  367. high = p[i] / 16;
  368. low = p[i] % 16;
  369. line[3 * (i % 16)] = toHex(high);
  370. line[3 * (i % 16) + 1] = toHex(low);
  371. line [52 + (i % 16)] = toChar(p[i]);
  372. if (i % 16 == 7 && i != (cbBuffer - 1)) {
  373. line[3 * (i % 16) + 2] = '-';
  374. }
  375. if (i % 16 == 15) {
  376. dprintf(" %s\n", line);
  377. spaceIt(line, 72);
  378. }
  379. }
  380. dprintf(" %s\n", line);
  381. }
  382. typedef
  383. BOOL
  384. (* PFuncLookupAccountNameA)(
  385. IN LPCSTR lpSystemName,
  386. IN LPCSTR lpAccountName,
  387. OUT PSID Sid,
  388. IN OUT LPDWORD cbSid,
  389. OUT LPSTR ReferencedDomainName,
  390. IN OUT LPDWORD cbReferencedDomainName,
  391. OUT PSID_NAME_USE peUse
  392. );
  393. BOOL
  394. WINAPI
  395. LsaLookupAccountNameA(
  396. IN LPCSTR lpSystemName,
  397. IN LPCSTR lpAccountName,
  398. OUT PSID Sid,
  399. IN OUT LPDWORD cbSid,
  400. OUT LPSTR ReferencedDomainName,
  401. IN OUT LPDWORD cbReferencedDomainName,
  402. OUT PSID_NAME_USE peUse
  403. )
  404. {
  405. PFuncLookupAccountNameA pFuncLookupAccountNameA = NULL;
  406. BOOL bRetval = FALSE;
  407. HMODULE hLib = LoadLibrary("advapi32.dll");
  408. if (hLib)
  409. {
  410. pFuncLookupAccountNameA = (PFuncLookupAccountNameA) GetProcAddress(hLib, "LookupAccountNameA");
  411. if (pFuncLookupAccountNameA)
  412. {
  413. bRetval = pFuncLookupAccountNameA(lpSystemName, lpAccountName, Sid, cbSid, ReferencedDomainName, cbReferencedDomainName, peUse);
  414. }
  415. FreeLibrary(hLib);
  416. }
  417. return bRetval;
  418. }
  419. typedef
  420. BOOL
  421. (* PFuncLookupAccountSidA)(
  422. IN LPCSTR lpSystemName,
  423. IN PSID Sid,
  424. OUT LPSTR Name,
  425. IN OUT LPDWORD cbName,
  426. OUT LPSTR ReferencedDomainName,
  427. IN OUT LPDWORD cbReferencedDomainName,
  428. OUT PSID_NAME_USE peUse
  429. );
  430. BOOL
  431. WINAPI
  432. LsaLookupAccountSidA(
  433. IN LPCSTR lpSystemName,
  434. IN PSID Sid,
  435. OUT LPSTR Name,
  436. IN OUT LPDWORD cbName,
  437. OUT LPSTR ReferencedDomainName,
  438. IN OUT LPDWORD cbReferencedDomainName,
  439. OUT PSID_NAME_USE peUse
  440. )
  441. {
  442. PFuncLookupAccountSidA pFuncLookupAccountSidA = NULL;
  443. BOOL bRetval = FALSE;
  444. HMODULE hLib = LoadLibrary("advapi32.dll");
  445. if (hLib)
  446. {
  447. pFuncLookupAccountSidA = (PFuncLookupAccountSidA) GetProcAddress(hLib, "LookupAccountSidA");
  448. if (pFuncLookupAccountSidA)
  449. {
  450. bRetval = pFuncLookupAccountSidA(lpSystemName, Sid, Name, cbName, ReferencedDomainName, cbReferencedDomainName, peUse);
  451. }
  452. FreeLibrary(hLib);
  453. }
  454. return bRetval;
  455. }
  456. LARGE_INTEGER ULONG642LargeInteger(IN ULONG64 value)
  457. {
  458. LARGE_INTEGER tmp = {0};
  459. C_ASSERT(sizeof(ULONG64) == sizeof(LARGE_INTEGER));
  460. memcpy(&tmp, &value, sizeof(LARGE_INTEGER));
  461. return tmp;
  462. }
  463. VOID
  464. ShowSystemTimeAsLocalTime(
  465. IN PCSTR pszBanner,
  466. IN ULONG64 ul64Time
  467. )
  468. {
  469. LARGE_INTEGER Time = ULONG642LargeInteger(ul64Time);
  470. LARGE_INTEGER LocalTime = {0};
  471. TIME_FIELDS TimeFields = {0};
  472. NTSTATUS Status = RtlSystemTimeToLocalTime(&Time, &LocalTime);
  473. if (!NT_SUCCESS(Status))
  474. {
  475. dprintf("Can't convert file time from GMT to Local time: 0x%lx\n", Status);
  476. }
  477. else
  478. {
  479. RtlTimeToTimeFields(&LocalTime, &TimeFields);
  480. if (pszBanner) {
  481. dprintf("%s %ld/%ld/%ld %ld:%2.2ld:%2.2ld (L%8.8lx H%8.8lx)\n",
  482. pszBanner,
  483. TimeFields.Month,
  484. TimeFields.Day,
  485. TimeFields.Year,
  486. TimeFields.Hour,
  487. TimeFields.Minute,
  488. TimeFields.Second,
  489. Time.LowPart,
  490. Time.HighPart);
  491. } else {
  492. dprintf("%ld/%ld/%ld %ld:%2.2ld:%2.2ld (L%8.8lx H%8.8lx)\n",
  493. TimeFields.Month,
  494. TimeFields.Day,
  495. TimeFields.Year,
  496. TimeFields.Hour,
  497. TimeFields.Minute,
  498. TimeFields.Second,
  499. Time.LowPart,
  500. Time.HighPart);
  501. }
  502. }
  503. }
  504. } // LSA_NS