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.

735 lines
22 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. util.c
  5. Abstract:
  6. Contains general functions.
  7. Author:
  8. Sanjay Anand (SanjayAn) Nov. 14, 1995
  9. Environment:
  10. User mode
  11. Revision History:
  12. Sanjay Anand (SanjayAn) Nov. 14, 1995
  13. Created
  14. --*/
  15. #include "defs.h"
  16. #define CONV_LOG_FILE_NAME TEXT("%SystemRoot%\\System32\\jetconv.exe")
  17. #define CONV_MSGFILE_SKEY TEXT("EventMessageFile")
  18. HANDLE EventlogHandle = NULL;
  19. NTSTATUS
  20. JCRegisterEventSrc()
  21. /*++
  22. Routine Description:
  23. This routine registers JetConv as an eventsource.
  24. Arguments:
  25. None.
  26. Return Value:
  27. None.
  28. --*/
  29. {
  30. TCHAR temp[] = "JetConv";
  31. TCHAR logName[MAX_PATH]=JCONV_LOG_KEY_PREFIX;
  32. TCHAR Buff[MAX_PATH];
  33. LONG RetVal = ERROR_SUCCESS;
  34. HKEY LogRoot;
  35. DWORD NewKeyInd;
  36. DWORD dwData;
  37. strcat(logName, temp);
  38. //
  39. // Create the registry keys so we can register as an event source
  40. //
  41. RetVal = RegCreateKeyEx(
  42. HKEY_LOCAL_MACHINE, //predefined key value
  43. logName, //subkey for JetConv
  44. 0, //must be zero (reserved)
  45. TEXT("Class"), //class -- may change in future
  46. REG_OPTION_NON_VOLATILE, //non-volatile information
  47. KEY_ALL_ACCESS, //we desire all access to the keyo
  48. NULL, //let key have default sec. attributes
  49. &LogRoot, //handle to key
  50. &NewKeyInd //is it a new key (out arg) -- not
  51. //looked at
  52. );
  53. if (RetVal != ERROR_SUCCESS)
  54. {
  55. MYDEBUG(("RegCreateKeyEx failed %lx for %s\n", RetVal, logName));
  56. return(RetVal);
  57. }
  58. /*
  59. Set the event id message file name
  60. */
  61. lstrcpy(Buff, CONV_LOG_FILE_NAME);
  62. /*
  63. Add the Event-ID message-file name to the subkey
  64. */
  65. RetVal = RegSetValueEx(
  66. LogRoot, //key handle
  67. CONV_MSGFILE_SKEY, //value name
  68. 0, //must be zero
  69. REG_EXPAND_SZ, //value type
  70. (LPBYTE)Buff,
  71. (lstrlen(Buff) + 1) * sizeof(TCHAR) //length of value data
  72. );
  73. if (RetVal != ERROR_SUCCESS)
  74. {
  75. MYDEBUG(("RegSetValueEx failed %lx for %s", RetVal, Buff));
  76. return(RetVal);
  77. }
  78. /*
  79. Set the supported data types flags
  80. */
  81. dwData = EVENTLOG_ERROR_TYPE |
  82. EVENTLOG_WARNING_TYPE |
  83. EVENTLOG_INFORMATION_TYPE;
  84. RetVal = RegSetValueEx (
  85. LogRoot, //subkey handle
  86. TEXT("TypesSupported"), //value name
  87. 0, //must be zero
  88. REG_DWORD, //value type
  89. (LPBYTE)&dwData, //Address of value data
  90. sizeof(DWORD) //length of value data
  91. );
  92. if (RetVal != ERROR_SUCCESS)
  93. {
  94. MYDEBUG(("RegSetValueEx failed %lx for TypesSupported on %s", RetVal, logName));
  95. return(RetVal);
  96. }
  97. /*
  98. * Done with the key. Close it
  99. */
  100. RetVal = RegCloseKey(LogRoot);
  101. if (RetVal != ERROR_SUCCESS)
  102. {
  103. MYDEBUG(("RegCloseKey failed %lx\n", RetVal));
  104. return(RetVal);
  105. }
  106. //
  107. // Register JetConv as an event source
  108. //
  109. strcpy(logName, temp);
  110. if (!(EventlogHandle = RegisterEventSource( NULL,
  111. logName))) {
  112. MYDEBUG(("RegisterEventSource failed %lx\n", GetLastError()));
  113. return STATUS_UNSUCCESSFUL;
  114. } else {
  115. MYDEBUG(("RegisterEventSource succeeded\n"));
  116. return STATUS_SUCCESS;
  117. }
  118. }
  119. NTSTATUS
  120. JCDeRegisterEventSrc()
  121. /*++
  122. Routine Description:
  123. This routine deregisters eventsources corresponding to those service that
  124. are installed in the system.
  125. Arguments:
  126. None.
  127. Return Value:
  128. NtStatus.
  129. --*/
  130. {
  131. if (EventlogHandle) {
  132. if (!DeregisterEventSource(EventlogHandle)) {
  133. MYDEBUG(("DeregisterEventSource failed: %lx for %s", GetLastError()));
  134. return STATUS_UNSUCCESSFUL;
  135. } else {
  136. return STATUS_SUCCESS;
  137. }
  138. }
  139. return STATUS_SUCCESS;
  140. }
  141. VOID
  142. JCLogEvent(
  143. DWORD EventId,
  144. LPSTR MsgTypeString1,
  145. LPSTR MsgTypeString2 OPTIONAL,
  146. LPSTR MsgTypeString3 OPTIONAL
  147. )
  148. /*++
  149. Routine Description:
  150. This routine logs an entry in the eventlog.
  151. Arguments:
  152. EventId - the event identifier
  153. MsgTypeString1 - string to be output
  154. MsgTypeString2 - string2 to be output (OPTIONAL)
  155. Return Value:
  156. None.
  157. --*/
  158. {
  159. LPSTR Strings[3];
  160. WORD numStr;
  161. Strings[0] = MsgTypeString1;
  162. Strings[1] = MsgTypeString2;
  163. Strings[2] = MsgTypeString3;
  164. if (MsgTypeString3) {
  165. numStr = 3;
  166. } else if (MsgTypeString2) {
  167. numStr = 2;
  168. } else {
  169. numStr = 1;
  170. }
  171. if( !ReportEvent(
  172. EventlogHandle,
  173. (WORD)EVENTLOG_INFORMATION_TYPE,
  174. 0, // event category
  175. EventId,
  176. NULL,
  177. numStr,
  178. 0,
  179. Strings,
  180. NULL) ) {
  181. MYDEBUG(("ReportEvent failed %ld.", GetLastError() ));
  182. }
  183. return;
  184. }
  185. VOID
  186. JCReadRegistry(
  187. IN PSERVICE_INFO pServiceInfo
  188. )
  189. /*++
  190. Routine Description:
  191. This routine reads the registry to determine which of the service
  192. among WINS, DHCP and RPL are installed. For those installed, it
  193. fills in the ServiceInfo structure.
  194. Arguments:
  195. pServiceInfo - Pointer to the service information struct.
  196. Return Value:
  197. None.
  198. --*/
  199. {
  200. HKEY hkey ;
  201. SERVICES i ;
  202. DWORD type ;
  203. DWORD size = 0 ;
  204. DWORD error;
  205. TCHAR tempPath[MAX_PATH];
  206. TCHAR servicePath[MAX_PATH];
  207. TCHAR parametersPath[MAX_PATH];
  208. TCHAR dbfilePath[MAX_PATH];
  209. TCHAR dbfileName[MAX_PATH];
  210. TCHAR backupFilePath[MAX_PATH];
  211. TCHAR logfilePath[MAX_PATH];
  212. HANDLE ServiceHandle, SCHandle;
  213. for ( i = 0; i < NUM_SERVICES; i++) {
  214. switch (i) {
  215. case WINS:
  216. strcpy(servicePath, WINS_REGISTRY_SERVICE_PATH);
  217. strcpy(parametersPath, WINS_REGISTRY_PARAMETERS_PATH);
  218. strcpy(dbfilePath, WINS_REGISTRY_DBFILE_PATH);
  219. strcpy(logfilePath, WINS_REGISTRY_LOGFILE_PATH);
  220. strcpy(backupFilePath, WINS_REGISTRY_BACKUP_PATH);
  221. break;
  222. case DHCP:
  223. strcpy(servicePath, DHCP_REGISTRY_SERVICE_PATH);
  224. strcpy(parametersPath, DHCP_REGISTRY_PARAMETERS_PATH);
  225. strcpy(dbfilePath, DHCP_REGISTRY_DBFILE_PATH);
  226. strcpy(dbfileName, DHCP_REGISTRY_DBFILE_NAME);
  227. // strcpy(logfilePath, DHCP_REGISTRY_LOGFILE_PATH);
  228. strcpy(backupFilePath, DHCP_REGISTRY_BACKUP_PATH);
  229. break;
  230. case RPL:
  231. strcpy(servicePath, RPL_REGISTRY_SERVICE_PATH);
  232. strcpy(parametersPath, RPL_REGISTRY_PARAMETERS_PATH);
  233. strcpy(dbfilePath, RPL_REGISTRY_DBFILE_PATH);
  234. // no such path
  235. // strcpy(logfilePath, RPL_REGISTRY_LOGFILE_PATH);
  236. // strcpy(backupFilePath, RPL_REGISTRY_BACKUP_PATH);
  237. break;
  238. }
  239. //
  240. // Check if service is installed - if the service name key is
  241. // present, it is installed.
  242. //
  243. if ((error = RegOpenKey(HKEY_LOCAL_MACHINE,
  244. servicePath,
  245. &hkey)) != ERROR_SUCCESS) {
  246. MYDEBUG(("RegOpenKey %s returned error: %lx\n", pServiceInfo[i].ServiceName, error));
  247. MYDEBUG(("%s not installed\n", pServiceInfo[i].ServiceName));
  248. pServiceInfo[i].Installed = FALSE;
  249. continue;
  250. } else {
  251. //
  252. // NtBug: 139281
  253. // Its likely that the regkey exists, but the service was DISABLED!
  254. //
  255. MYDEBUG(("*************************Opening SC Manager\n"));
  256. SCHandle = OpenSCManager(
  257. NULL,
  258. NULL,
  259. SC_MANAGER_CONNECT |
  260. SC_MANAGER_ENUMERATE_SERVICE |
  261. SC_MANAGER_QUERY_LOCK_STATUS
  262. );
  263. if( SCHandle != NULL ) {
  264. ServiceHandle = OpenService(
  265. SCHandle,
  266. pServiceInfo[i].ServiceName,
  267. SERVICE_QUERY_CONFIG
  268. );
  269. if( ServiceHandle == NULL ) {
  270. MYDEBUG(("SCManager tells us that the service %s is cant be opened: %lx!\n", pServiceInfo[i].ServiceName, GetLastError()));
  271. pServiceInfo[i].Installed = FALSE;
  272. CloseServiceHandle(SCHandle);
  273. continue;
  274. } else {
  275. LPQUERY_SERVICE_CONFIG ServiceConfig;
  276. DWORD cbBufSize;
  277. DWORD cbBytesNeeded;
  278. BOOL result = FALSE;
  279. cbBytesNeeded = 0;
  280. //
  281. // First send 0 buffer to figure out what the length needs to be.
  282. //
  283. result = QueryServiceConfig(
  284. ServiceHandle, // handle of service
  285. NULL, // address of service config. structure
  286. 0, // size of service configuration buffer
  287. &cbBytesNeeded // address of variable for bytes needed
  288. );
  289. if (!result) {
  290. MYDEBUG(("QueryService failed due to :%d \n", GetLastError()));
  291. } else {
  292. MYDEBUG(("QueryService PASSED with NULL. Shouldnt happen.\n"));
  293. }
  294. ServiceConfig = (LPQUERY_SERVICE_CONFIG) malloc (cbBytesNeeded);
  295. cbBufSize = cbBytesNeeded;
  296. if (NULL == ServiceConfig) {
  297. MYDEBUG(("Can't alloc memory to query the SC\n"));
  298. pServiceInfo[i].Installed = FALSE;
  299. MYDEBUG(("SERVICE %s is DISABLED\n", pServiceInfo[i].ServiceName));
  300. CloseServiceHandle(ServiceHandle);
  301. CloseServiceHandle(SCHandle);
  302. continue;
  303. }
  304. if (!QueryServiceConfig(
  305. ServiceHandle, // handle of service
  306. ServiceConfig, // address of service config. structure
  307. cbBufSize, // size of service configuration buffer
  308. &cbBytesNeeded // address of variable for bytes needed
  309. )) {
  310. free(ServiceConfig);
  311. MYDEBUG(("Things didnt work:%lx, %d , %d\n", GetLastError(), cbBufSize, cbBytesNeeded));
  312. pServiceInfo[i].Installed = FALSE;
  313. MYDEBUG(("SERVICE %s is DISABLED\n", pServiceInfo[i].ServiceName));
  314. CloseServiceHandle(ServiceHandle);
  315. CloseServiceHandle(SCHandle);
  316. continue;
  317. } else {
  318. if (SERVICE_DISABLED == ServiceConfig->dwStartType) {
  319. free(ServiceConfig);
  320. pServiceInfo[i].Installed = FALSE;
  321. MYDEBUG(("SERVICE %s is DISABLED\n", pServiceInfo[i].ServiceName));
  322. CloseServiceHandle(ServiceHandle);
  323. CloseServiceHandle(SCHandle);
  324. continue;
  325. }
  326. free(ServiceConfig);
  327. }
  328. CloseServiceHandle(ServiceHandle);
  329. }
  330. CloseServiceHandle(SCHandle);
  331. } else {
  332. MYDEBUG(("Cant open SCManager:%;x!\n", GetLastError()));
  333. MYDEBUG(("%s not installed\n", pServiceInfo[i].ServiceName));
  334. pServiceInfo[i].Installed = FALSE;
  335. continue;
  336. }
  337. }
  338. pServiceInfo[i].Installed = TRUE;
  339. size = MAX_PATH;
  340. if ((error = JCRegisterEventSrc()) != ERROR_SUCCESS) {
  341. MYDEBUG(("JCRegisterEventSrc failed\n"));
  342. pServiceInfo[i].Installed = FALSE;
  343. continue;
  344. }
  345. //
  346. // Open the parameters key
  347. //
  348. if ((error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  349. parametersPath,
  350. 0,
  351. KEY_ALL_ACCESS,
  352. &hkey)) != ERROR_SUCCESS) {
  353. MYDEBUG(("RegOpenKeyEx %s\\Parameters returned error: %lx\n", pServiceInfo[i].ServiceName, error));
  354. } else {
  355. //
  356. // Read in the path to the Dbase file.
  357. //
  358. size = MAX_PATH;
  359. if ((error = RegQueryValueEx(hkey,
  360. dbfilePath,
  361. NULL,
  362. &type,
  363. pServiceInfo[i].DBPath,
  364. &size)) != ERROR_SUCCESS) {
  365. MYDEBUG(("RegQueryValueEx of %s dbpath failed: %lx\n", pServiceInfo[i].ServiceName, error));
  366. //
  367. // If no path parameter, it shd be in %systemroot%\system32\<service> - the path was initialized to
  368. // the default.
  369. //
  370. MYDEBUG(("%s dbfile path not present; assuming it is in %s\n",
  371. pServiceInfo[i].ServiceName, pServiceInfo[i].DBPath));
  372. } else {
  373. pServiceInfo[i].DefaultDbPath = FALSE;
  374. //
  375. // DHCP splits the name and path
  376. //
  377. if (i == DHCP) {
  378. TCHAR dhcpDBFileName[MAX_PATH];
  379. //
  380. // Copy this path to the logfilepath too.
  381. //
  382. strcpy(pServiceInfo[i].LogFilePath, pServiceInfo[i].DBPath);
  383. //
  384. // Read the name too
  385. //
  386. size = MAX_PATH;
  387. if ((error = RegQueryValueEx(hkey,
  388. dbfileName,
  389. NULL,
  390. &type,
  391. dhcpDBFileName,
  392. &size)) != ERROR_SUCCESS) {
  393. MYDEBUG(("RegQueryValueEx of %s dbName failed: %lx\n", pServiceInfo[i].ServiceName, error));
  394. //
  395. // If no path parameter, it shd be in %systemroot%\system32\<service> - the path was initialized to
  396. // the default.
  397. //
  398. MYDEBUG(("%s dbfile name not present; assuming it is dhcp.mdb\n",
  399. pServiceInfo[i].ServiceName));
  400. strcat(pServiceInfo[i].DBPath, TEXT("\\dhcp.mdb"));
  401. } else {
  402. strcat(pServiceInfo[i].DBPath, TEXT("\\"));
  403. strcat(pServiceInfo[i].DBPath, dhcpDBFileName);
  404. }
  405. } else if (i == RPL) {
  406. //
  407. // Copy this path to the logfilepath too.
  408. //
  409. strcpy(pServiceInfo[i].LogFilePath, pServiceInfo[i].DBPath);
  410. //
  411. // Copy this path to the backuppath too
  412. //
  413. strcpy(pServiceInfo[i].BackupPath, pServiceInfo[i].DBPath);
  414. strcat(pServiceInfo[i].BackupPath, TEXT("\\backup"));
  415. //
  416. // The DBFile is always called rplsvc.mdb
  417. //
  418. strcat(pServiceInfo[i].DBPath, TEXT("\\rplsvc.mdb"));
  419. }
  420. }
  421. //
  422. // Read in the path to the Log file.
  423. // In case of RPL, no such paths exist.
  424. // Assume they are in the same directory as the database files.
  425. //
  426. if (i != RPL) {
  427. //
  428. // DHCP has no logfilepath
  429. //
  430. if (i != DHCP) {
  431. size = MAX_PATH;
  432. if ((error = RegQueryValueEx(hkey,
  433. logfilePath,
  434. NULL,
  435. &type,
  436. pServiceInfo[i].LogFilePath,
  437. &size)) != ERROR_SUCCESS) {
  438. MYDEBUG(("RegQueryValueEx of %s logfilepath failed: %lx\n", pServiceInfo[i].ServiceName, error));
  439. //
  440. // If no path parameter, it shd be in %systemroot%\system32\<service> - the path was initialized to
  441. // the default.
  442. //
  443. MYDEBUG(("%s logfile path not present; assuming it is in %s\n",
  444. pServiceInfo[i].ServiceName, pServiceInfo[i].LogFilePath));
  445. } else {
  446. pServiceInfo[i].DefaultLogFilePath = FALSE;
  447. }
  448. }
  449. //
  450. // Read in the path to the backup file.
  451. //
  452. size = MAX_PATH;
  453. if ((error = RegQueryValueEx(hkey,
  454. backupFilePath,
  455. NULL,
  456. &type,
  457. pServiceInfo[i].BackupPath,
  458. &size)) != ERROR_SUCCESS) {
  459. MYDEBUG(("RegQueryValueEx of %s BackupPath failed: %lx\n", pServiceInfo[i].ServiceName, error));
  460. //
  461. // If no path parameter, it shd be in %systemroot%\system32\<service> - the path was initialized to
  462. // the default.
  463. //
  464. MYDEBUG(("%s backupfile path not present; assuming it is in %s\n",
  465. pServiceInfo[i].ServiceName, pServiceInfo[i].BackupPath));
  466. }
  467. }
  468. }
  469. //
  470. // Expand the environment variables in the path.
  471. //
  472. strcpy(tempPath, pServiceInfo[i].DBPath);
  473. if ((size = ExpandEnvironmentStrings( tempPath,
  474. pServiceInfo[i].DBPath,
  475. MAX_PATH)) == 0) {
  476. error = GetLastError();
  477. MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", pServiceInfo[i].ServiceName, error));
  478. }
  479. SystemDrive[0] = pServiceInfo[i].DBPath[0];
  480. SystemDrive[1] = pServiceInfo[i].DBPath[1];
  481. SystemDrive[2] = pServiceInfo[i].DBPath[2];
  482. SystemDrive[3] = '\0';
  483. MYDEBUG(("pServiceInfo[i].DbasePath: %s\n", pServiceInfo[i].DBPath));
  484. //
  485. // Expand the environment variables in the log file path.
  486. //
  487. strcpy(tempPath, pServiceInfo[i].LogFilePath);
  488. if ((size = ExpandEnvironmentStrings( tempPath,
  489. pServiceInfo[i].LogFilePath,
  490. MAX_PATH)) == 0) {
  491. error = GetLastError();
  492. MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", pServiceInfo[i].ServiceName, error));
  493. }
  494. MYDEBUG(("pServiceInfo[i].LogFilePath: %s\n", pServiceInfo[i].LogFilePath));
  495. //
  496. // Expand the environment variables in the backup file path.
  497. //
  498. strcpy(tempPath, pServiceInfo[i].BackupPath);
  499. if ((size = ExpandEnvironmentStrings( tempPath,
  500. pServiceInfo[i].BackupPath,
  501. MAX_PATH)) == 0) {
  502. error = GetLastError();
  503. MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", pServiceInfo[i].ServiceName, error));
  504. }
  505. MYDEBUG(("pServiceInfo[i].BackupPath: %s\n", pServiceInfo[i].BackupPath));
  506. }
  507. for ( i = 0; i < NUM_SERVICES; i++) {
  508. if (pServiceInfo[i].Installed) {
  509. MYDEBUG(("Service %s is Installed\n", pServiceInfo[i].ServiceName));
  510. } else {
  511. MYDEBUG(("Service %s is NOT Installed\n", pServiceInfo[i].ServiceName));
  512. }
  513. }
  514. }
  515. VOID
  516. JCGetMutex (
  517. IN HANDLE hMutex,
  518. IN DWORD To
  519. )
  520. /*++
  521. Routine Description:
  522. This routine waits on a mutex object.
  523. Arguments:
  524. hMutex - handle to mutex
  525. To - time to wait
  526. Return Value:
  527. None.
  528. --*/
  529. {
  530. if (WaitForSingleObject (hMutex, To) == WAIT_FAILED) {
  531. MYDEBUG(("WaitForSingleObject failed: %lx\n", GetLastError()));
  532. }
  533. }
  534. VOID
  535. JCFreeMutex (
  536. IN HANDLE hMutex
  537. )
  538. /*++
  539. Routine Description:
  540. This routine releases a mutex.
  541. Arguments:
  542. hMutex - handle to mutex
  543. Return Value:
  544. None.
  545. --*/
  546. {
  547. if (!ReleaseMutex(hMutex)) {
  548. MYDEBUG(("ReleaseMutex failed: %lx\n", GetLastError()));
  549. }
  550. }