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.

407 lines
10 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // File: tlsbkupc.cpp
  6. //
  7. // Contents:
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #include "pch.cpp"
  13. #include "locks.h"
  14. #include "tlsbkup.h"
  15. #define STRSAFE_NO_DEPRECATE
  16. #include <strsafe.h>
  17. #define LSERVER_REGISTRY_BASE _TEXT("SYSTEM\\CurrentControlSet\\Services\\")
  18. #define LSERVER_PARAMETERS _TEXT("Parameters")
  19. #define LSERVER_PARAMETERS_DBPATH _TEXT("DBPath") // database file
  20. #define LSERVER_PARAMETERS_DBFILE _TEXT("DBFile") // database file
  21. #define SZSERVICENAME _TEXT("TermServLicensing")
  22. #define LSERVER_DEFAULT_DBPATH _TEXT("%SYSTEMROOT%\\SYSTEM32\\LSERVER\\")
  23. #define LSERVER_DEFAULT_EDB _TEXT("TLSLic.edb")
  24. #define TLSBACKUP_EXPORT_DIR _TEXT("Export")
  25. TCHAR g_szDatabaseDir[MAX_PATH+1];
  26. TCHAR g_szDatabaseFile[MAX_PATH+1];
  27. TCHAR g_szExportedDb[MAX_PATH+1];
  28. TCHAR g_szDatabaseFname[MAX_PATH+1];
  29. CCriticalSection g_ImportExportLock;
  30. DWORD GetDatabasePaths()
  31. {
  32. DWORD Status;
  33. HKEY hKey = NULL;
  34. DWORD dwBuffer;
  35. TCHAR szDbPath[MAX_PATH+1];
  36. TCHAR *pszDatabaseEnd;
  37. size_t cbRemaining;
  38. HRESULT hr;
  39. //-------------------------------------------------------------------
  40. //
  41. // Open HKLM\system\currentcontrolset\sevices\termservlicensing\parameters
  42. //
  43. //-------------------------------------------------------------------
  44. Status = RegCreateKeyEx(
  45. HKEY_LOCAL_MACHINE,
  46. LSERVER_REGISTRY_BASE SZSERVICENAME _TEXT("\\") LSERVER_PARAMETERS,
  47. 0,
  48. NULL,
  49. REG_OPTION_NON_VOLATILE,
  50. KEY_ALL_ACCESS,
  51. NULL,
  52. &hKey,
  53. NULL
  54. );
  55. if(Status != ERROR_SUCCESS)
  56. {
  57. return Status;
  58. }
  59. //-------------------------------------------------------------------
  60. //
  61. // Get database file location and file name
  62. //
  63. //-------------------------------------------------------------------
  64. dwBuffer = sizeof(szDbPath) / sizeof(szDbPath[0]);
  65. Status = RegQueryValueEx(
  66. hKey,
  67. LSERVER_PARAMETERS_DBPATH,
  68. NULL,
  69. NULL,
  70. (LPBYTE)szDbPath,
  71. &dwBuffer
  72. );
  73. if(Status != ERROR_SUCCESS)
  74. {
  75. //
  76. // use default value,
  77. //
  78. _tcscpy(
  79. szDbPath,
  80. LSERVER_DEFAULT_DBPATH
  81. );
  82. }
  83. //
  84. // Get database file name
  85. //
  86. dwBuffer = sizeof(g_szDatabaseFname) / sizeof(g_szDatabaseFname[0]);
  87. Status = RegQueryValueEx(
  88. hKey,
  89. LSERVER_PARAMETERS_DBFILE,
  90. NULL,
  91. NULL,
  92. (LPBYTE)g_szDatabaseFname,
  93. &dwBuffer
  94. );
  95. if(Status != ERROR_SUCCESS)
  96. {
  97. //
  98. // Use default value.
  99. //
  100. _tcscpy(
  101. g_szDatabaseFname,
  102. LSERVER_DEFAULT_EDB
  103. );
  104. }
  105. RegCloseKey(hKey);
  106. //
  107. // Always expand DB Path.
  108. //
  109. Status = ExpandEnvironmentStrings(
  110. szDbPath,
  111. g_szDatabaseDir,
  112. sizeof(g_szDatabaseDir) / sizeof(g_szDatabaseDir[0])
  113. );
  114. if(Status == 0)
  115. {
  116. // can't expand environment variable, error out.
  117. return GetLastError();
  118. }
  119. Status = 0;
  120. if(g_szDatabaseDir[_tcslen(g_szDatabaseDir) - 1] != _TEXT('\\'))
  121. {
  122. // JetBlue needs this.
  123. StringCbCat(g_szDatabaseDir, sizeof(g_szDatabaseDir), _TEXT("\\"));
  124. }
  125. //
  126. // Full path to database file
  127. //
  128. hr = StringCbCopyEx(g_szDatabaseFile,sizeof(g_szDatabaseFile),g_szDatabaseDir,&pszDatabaseEnd, &cbRemaining,0);
  129. if (FAILED(hr))
  130. {
  131. return HRESULT_CODE(hr);
  132. }
  133. hr = StringCbCopyEx(pszDatabaseEnd,cbRemaining,g_szDatabaseFname,NULL, NULL,0);
  134. if (FAILED(hr))
  135. {
  136. return HRESULT_CODE(hr);
  137. }
  138. hr = StringCbCopyEx(g_szExportedDb,sizeof(g_szExportedDb),g_szDatabaseDir,&pszDatabaseEnd, &cbRemaining,0);
  139. if (FAILED(hr))
  140. {
  141. return HRESULT_CODE(hr);
  142. }
  143. hr = StringCbCopyEx(pszDatabaseEnd,cbRemaining,TLSBACKUP_EXPORT_DIR,NULL, NULL,0);
  144. if (FAILED(hr))
  145. {
  146. return HRESULT_CODE(hr);
  147. }
  148. return Status;
  149. }
  150. HRESULT WINAPI
  151. I_ExportTlsDatabaseC()
  152. {
  153. DWORD dwRet = 0;
  154. LPTSTR pszStringBinding;
  155. TCHAR pComputer[MAX_COMPUTERNAME_LENGTH + 1];
  156. DWORD dwSize = sizeof(pComputer) / sizeof(TCHAR);
  157. RPC_STATUS Status = RPC_S_OK;
  158. HRESULT hr;
  159. TCHAR *pszDatabaseEnd;
  160. size_t cbRemaining;
  161. if (!GetComputerName(pComputer,&dwSize))
  162. {
  163. return GetLastError();
  164. }
  165. Status = RpcStringBindingCompose(NULL,TEXT("ncalrpc"),pComputer,NULL,NULL,&pszStringBinding);
  166. if (Status)
  167. {
  168. return Status;
  169. }
  170. Status = RpcBindingFromStringBinding(pszStringBinding,
  171. &TermServLicensingBackup_IfHandle);
  172. if (Status)
  173. {
  174. RpcStringFree(&pszStringBinding);
  175. goto TryCopyFile;
  176. }
  177. RpcTryExcept {
  178. dwRet = ExportTlsDatabase();
  179. }
  180. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode())) {
  181. Status = RpcExceptionCode();
  182. }
  183. RpcEndExcept;
  184. RpcStringFree(&pszStringBinding);
  185. RpcBindingFree(&TermServLicensingBackup_IfHandle);
  186. #if DBG
  187. {
  188. char szStatusCode[256];
  189. sprintf( szStatusCode, "I_ExportTlsDatabaseC() returns %d\n", Status );
  190. OutputDebugStringA( szStatusCode );
  191. }
  192. #endif
  193. //
  194. // Only actually touch file when server is not available
  195. //
  196. if ( RPC_S_OK == Status)
  197. {
  198. return dwRet;
  199. }
  200. TryCopyFile:
  201. Status = GetDatabasePaths();
  202. if (Status != 0)
  203. {
  204. return Status;
  205. }
  206. CreateDirectoryEx(g_szDatabaseDir,
  207. g_szExportedDb,
  208. NULL); // Ignore errors, they'll show up in CopyFile
  209. hr = StringCbCatEx(g_szExportedDb, sizeof(g_szExportedDb), _TEXT("\\"), &pszDatabaseEnd, &cbRemaining,0);
  210. if (FAILED(hr))
  211. {
  212. return HRESULT_CODE(hr);
  213. }
  214. hr = StringCbCopyEx(pszDatabaseEnd,cbRemaining,g_szDatabaseFname,NULL, NULL,0);
  215. if (FAILED(hr))
  216. {
  217. return HRESULT_CODE(hr);
  218. }
  219. // Copy database file
  220. if (!CopyFile(g_szDatabaseFile,g_szExportedDb,FALSE))
  221. {
  222. return GetLastError();
  223. }
  224. return 0; // Success
  225. }
  226. HRESULT WINAPI
  227. ExportTlsDatabaseC()
  228. {
  229. // avoid compiler error C2712
  230. // no need for multi-process save.
  231. CCriticalSectionLocker lock( g_ImportExportLock );
  232. return I_ExportTlsDatabaseC();
  233. }
  234. HRESULT WINAPI
  235. I_ImportTlsDatabaseC()
  236. {
  237. DWORD dwRet = 0;
  238. LPTSTR pszStringBinding;
  239. TCHAR pComputer[MAX_COMPUTERNAME_LENGTH + 1];
  240. DWORD dwSize = sizeof(pComputer) / sizeof(TCHAR);
  241. RPC_STATUS Status = RPC_S_OK;
  242. HANDLE hFile;
  243. SYSTEMTIME systime;
  244. FILETIME ft;
  245. HRESULT hr;
  246. TCHAR *pszDatabaseEnd;
  247. size_t cbRemaining;
  248. if (!GetComputerName(pComputer,&dwSize))
  249. {
  250. return GetLastError();
  251. }
  252. Status = RpcStringBindingCompose(NULL,TEXT("ncalrpc"),pComputer,NULL,NULL,&pszStringBinding);
  253. if (Status)
  254. {
  255. return Status;
  256. }
  257. Status = RpcBindingFromStringBinding(pszStringBinding,
  258. &TermServLicensingBackup_IfHandle);
  259. if (Status)
  260. {
  261. RpcStringFree(&pszStringBinding);
  262. goto TouchFile;
  263. }
  264. RpcTryExcept {
  265. dwRet = ImportTlsDatabase();
  266. }
  267. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode())) {
  268. Status = RpcExceptionCode();
  269. }
  270. RpcEndExcept;
  271. RpcStringFree(&pszStringBinding);
  272. RpcBindingFree(&TermServLicensingBackup_IfHandle);
  273. #if DBG
  274. {
  275. char szStatusCode[256];
  276. sprintf( szStatusCode, "I_ImportTlsDatabaseC() returns %d\n", Status );
  277. OutputDebugStringA( szStatusCode );
  278. }
  279. #endif
  280. //
  281. // Only actually touch file when server is not available
  282. //
  283. if ( RPC_S_OK == Status )
  284. {
  285. return(dwRet);
  286. }
  287. TouchFile:
  288. Status = GetDatabasePaths();
  289. if (Status != 0)
  290. {
  291. return Status;
  292. }
  293. hr = StringCbCatEx(g_szExportedDb, sizeof(g_szExportedDb), _TEXT("\\"), &pszDatabaseEnd, &cbRemaining,0);
  294. if (FAILED(hr))
  295. {
  296. return HRESULT_CODE(hr);
  297. }
  298. hr = StringCbCopyEx(pszDatabaseEnd,cbRemaining,g_szDatabaseFname,NULL, NULL,0);
  299. if (FAILED(hr))
  300. {
  301. return HRESULT_CODE(hr);
  302. }
  303. GetSystemTime(&systime);
  304. if (!SystemTimeToFileTime(&systime,&ft))
  305. {
  306. return GetLastError();
  307. }
  308. hFile = CreateFile(g_szExportedDb,
  309. GENERIC_WRITE,
  310. 0,
  311. NULL,
  312. OPEN_EXISTING,
  313. FILE_ATTRIBUTE_NORMAL,
  314. NULL);
  315. if (hFile == INVALID_HANDLE_VALUE)
  316. {
  317. return GetLastError();
  318. }
  319. if (!SetFileTime(hFile,
  320. NULL, // Creation time
  321. NULL, // Last access time
  322. &ft)) // Last write time
  323. {
  324. CloseHandle(hFile);
  325. return GetLastError();
  326. }
  327. CloseHandle(hFile);
  328. return 0; // Success
  329. }
  330. HRESULT WINAPI
  331. ImportTlsDatabaseC()
  332. {
  333. // avoid compiler error C2712
  334. // no need for multi-process save.
  335. CCriticalSectionLocker lock( g_ImportExportLock );
  336. return I_ImportTlsDatabaseC();
  337. }