Source code of Windows XP (NT5)
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.

339 lines
7.4 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. util.c
  5. Abstract:
  6. This module contains the shared utility rountines for dealing with
  7. sid to string conversion, services, path manipulation etc.
  8. Author:
  9. Cenk Ergan (cenke) - 2001/05/07
  10. Environment:
  11. User Mode
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <ginacomn.h>
  18. /***************************************************************************\
  19. * Sid To String routines
  20. *
  21. * GetUserSid - Builds a user's sid from his token.
  22. * GetSidString - Builds a sid string from a user's token.
  23. * DeleteSidString - Free's sid string allocated by GetSidString.
  24. *
  25. * History:
  26. * 03-23-01 Cenke Copied from userinit\gposcript.cpp
  27. * 06-07-01 Cenke Fixed memory leak
  28. \***************************************************************************/
  29. PSID
  30. GcGetUserSid(
  31. HANDLE UserToken
  32. )
  33. {
  34. PTOKEN_USER pUser;
  35. PTOKEN_USER pTemp;
  36. PSID pSid;
  37. DWORD BytesRequired = 200;
  38. NTSTATUS status;
  39. //
  40. // Allocate space for the user info
  41. //
  42. pUser = (PTOKEN_USER) LocalAlloc( LMEM_FIXED, BytesRequired );
  43. if ( !pUser )
  44. {
  45. return 0;
  46. }
  47. //
  48. // Read in the UserInfo
  49. //
  50. status = NtQueryInformationToken(
  51. UserToken, // Handle
  52. TokenUser, // TokenInformationClass
  53. pUser, // TokenInformation
  54. BytesRequired, // TokenInformationLength
  55. &BytesRequired // ReturnLength
  56. );
  57. if ( status == STATUS_BUFFER_TOO_SMALL )
  58. {
  59. //
  60. // Allocate a bigger buffer and try again.
  61. //
  62. pTemp = (PTOKEN_USER) LocalReAlloc( pUser, BytesRequired, LMEM_MOVEABLE );
  63. if ( !pTemp )
  64. {
  65. LocalFree(pUser);
  66. return 0;
  67. }
  68. pUser = pTemp;
  69. status = NtQueryInformationToken(
  70. UserToken, // Handle
  71. TokenUser, // TokenInformationClass
  72. pUser, // TokenInformation
  73. BytesRequired, // TokenInformationLength
  74. &BytesRequired // ReturnLength
  75. );
  76. }
  77. if ( !NT_SUCCESS(status) )
  78. {
  79. LocalFree(pUser);
  80. return 0;
  81. }
  82. BytesRequired = RtlLengthSid(pUser->User.Sid);
  83. pSid = LocalAlloc(LMEM_FIXED, BytesRequired);
  84. if ( !pSid )
  85. {
  86. LocalFree(pUser);
  87. return NULL;
  88. }
  89. status = RtlCopySid(BytesRequired, pSid, pUser->User.Sid);
  90. LocalFree(pUser);
  91. if ( !NT_SUCCESS(status) )
  92. {
  93. LocalFree(pSid);
  94. pSid = 0;
  95. }
  96. return pSid;
  97. }
  98. LPWSTR
  99. GcGetSidString(
  100. HANDLE UserToken
  101. )
  102. {
  103. NTSTATUS NtStatus;
  104. PSID UserSid;
  105. UNICODE_STRING UnicodeString;
  106. //
  107. // Get the user sid
  108. //
  109. UserSid = GcGetUserSid( UserToken );
  110. if ( !UserSid )
  111. {
  112. return 0;
  113. }
  114. //
  115. // Convert user SID to a string.
  116. //
  117. NtStatus = RtlConvertSidToUnicodeString(&UnicodeString,
  118. UserSid,
  119. (BOOLEAN)TRUE ); // Allocate
  120. LocalFree( UserSid );
  121. if ( !NT_SUCCESS(NtStatus) )
  122. {
  123. return 0;
  124. }
  125. return UnicodeString.Buffer ;
  126. }
  127. VOID
  128. GcDeleteSidString(
  129. LPWSTR SidString
  130. )
  131. {
  132. UNICODE_STRING String;
  133. RtlInitUnicodeString( &String, SidString );
  134. RtlFreeUnicodeString( &String );
  135. }
  136. /***************************************************************************\
  137. * GcWaitForServiceToStart
  138. *
  139. * Waits for the specified service to start.
  140. *
  141. * History:
  142. * 03-23-01 Cenke Copied from winlogon\wlxutil.c
  143. \***************************************************************************/
  144. BOOL
  145. GcWaitForServiceToStart (
  146. LPTSTR lpServiceName,
  147. DWORD dwMaxWait
  148. )
  149. {
  150. BOOL bStarted = FALSE;
  151. DWORD dwSize = 512;
  152. DWORD StartTickCount;
  153. SC_HANDLE hScManager = NULL;
  154. SC_HANDLE hService = NULL;
  155. SERVICE_STATUS ServiceStatus;
  156. LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
  157. //
  158. // OpenSCManager and the service.
  159. //
  160. hScManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
  161. if (!hScManager) {
  162. goto Exit;
  163. }
  164. hService = OpenService(hScManager, lpServiceName,
  165. SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS);
  166. if (!hService) {
  167. goto Exit;
  168. }
  169. //
  170. // Query if the service is going to start
  171. //
  172. lpServiceConfig = LocalAlloc (LPTR, dwSize);
  173. if (!lpServiceConfig) {
  174. goto Exit;
  175. }
  176. if (!QueryServiceConfig (hService, lpServiceConfig, dwSize, &dwSize)) {
  177. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
  178. goto Exit;
  179. }
  180. LocalFree (lpServiceConfig);
  181. lpServiceConfig = LocalAlloc (LPTR, dwSize);
  182. if (!lpServiceConfig) {
  183. goto Exit;
  184. }
  185. if (!QueryServiceConfig (hService, lpServiceConfig, dwSize, &dwSize)) {
  186. goto Exit;
  187. }
  188. }
  189. if (lpServiceConfig->dwStartType != SERVICE_AUTO_START) {
  190. goto Exit;
  191. }
  192. //
  193. // Loop until the service starts or we think it never will start
  194. // or we've exceeded our maximum time delay.
  195. //
  196. StartTickCount = GetTickCount();
  197. while (!bStarted) {
  198. if ((GetTickCount() - StartTickCount) > dwMaxWait) {
  199. break;
  200. }
  201. if (!QueryServiceStatus(hService, &ServiceStatus )) {
  202. break;
  203. }
  204. if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) {
  205. if (ServiceStatus.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED) {
  206. Sleep(500);
  207. } else {
  208. break;
  209. }
  210. } else if ( (ServiceStatus.dwCurrentState == SERVICE_RUNNING) ||
  211. (ServiceStatus.dwCurrentState == SERVICE_CONTINUE_PENDING) ||
  212. (ServiceStatus.dwCurrentState == SERVICE_PAUSE_PENDING) ||
  213. (ServiceStatus.dwCurrentState == SERVICE_PAUSED) ) {
  214. bStarted = TRUE;
  215. } else if (ServiceStatus.dwCurrentState == SERVICE_START_PENDING) {
  216. Sleep(500);
  217. } else {
  218. Sleep(500);
  219. }
  220. }
  221. Exit:
  222. if (lpServiceConfig) {
  223. LocalFree (lpServiceConfig);
  224. }
  225. if (hService) {
  226. CloseServiceHandle(hService);
  227. }
  228. if (hScManager) {
  229. CloseServiceHandle(hScManager);
  230. }
  231. return bStarted;
  232. }
  233. /***************************************************************************\
  234. * GcCheckSlash
  235. *
  236. * Checks for an ending slash and adds one if it is missing.
  237. *
  238. * Parameters: lpDir - directory
  239. * Return: Pointer to the end of the string
  240. *
  241. * History:
  242. * 06-19-95 EricFlo Created
  243. \***************************************************************************/
  244. LPTSTR
  245. GcCheckSlash (
  246. LPTSTR lpDir
  247. )
  248. {
  249. LPTSTR lpEnd;
  250. lpEnd = lpDir + lstrlen(lpDir);
  251. if (*(lpEnd - 1) != TEXT('\\')) {
  252. *lpEnd = TEXT('\\');
  253. lpEnd++;
  254. *lpEnd = TEXT('\0');
  255. }
  256. return lpEnd;
  257. }
  258. /***************************************************************************\
  259. * GcIsUNCPath
  260. *
  261. * History:
  262. * 2-28-92 Johannec Created
  263. *
  264. \***************************************************************************/
  265. BOOL
  266. GcIsUNCPath(
  267. LPTSTR lpPath
  268. )
  269. {
  270. if (lpPath[0] == TEXT('\\') && lpPath[1] == TEXT('\\')) {
  271. return(TRUE);
  272. }
  273. return(FALSE);
  274. }