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.

588 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. receive.c
  5. Abstract:
  6. APIs for the server-side RPC support for the Checkpoint Manager
  7. Author:
  8. John Vert (jvert) 1/14/1997
  9. Revision History:
  10. --*/
  11. #include "cpp.h"
  12. error_status_t
  13. CppDepositCheckpoint(
  14. handle_t IDL_handle,
  15. LPCWSTR ResourceId,
  16. DWORD dwCheckpointId,
  17. BYTE_PIPE CheckpointData,
  18. BOOLEAN fCryptoCheckpoint
  19. )
  20. /*++
  21. Routine Description:
  22. Server side RPC to allow other nodes to checkpoint data to the
  23. quorum disk.
  24. Arguments:
  25. IDL_handle - RPC binding handle, not used.
  26. ResourceId - Name of the resource whose data is being checkpointed
  27. dwCheckpointId - Unique identifier of the checkpoint
  28. CheckpointData - pipe through which checkpoint data can be retrieved.
  29. fCryptoCheckpoint - Indicates if the checkpoint is a crypto checkpoint
  30. Return Value:
  31. ERROR_SUCCESS if successful
  32. Win32 error code otherwise
  33. --*/
  34. {
  35. DWORD Status = ERROR_SUCCESS;
  36. LPWSTR FileName = NULL;
  37. LPWSTR DirectoryName = NULL;
  38. BOOL Success;
  39. PFM_RESOURCE Resource;
  40. ACQUIRE_SHARED_LOCK(gQuoLock);
  41. Resource = OmReferenceObjectById(ObjectTypeResource, ResourceId);
  42. if (Resource == NULL)
  43. {
  44. Status = ERROR_FILE_NOT_FOUND;
  45. goto FnExit;
  46. }
  47. Status = CppGetCheckpointFile(Resource,
  48. dwCheckpointId,
  49. &DirectoryName,
  50. &FileName,
  51. NULL,
  52. fCryptoCheckpoint);
  53. OmDereferenceObject(Resource);
  54. if (Status != ERROR_SUCCESS)
  55. {
  56. ClRtlLogPrint(LOG_CRITICAL,
  57. "[CP] CppDepositCheckpoint - CppGetCheckpointFile failed %1!d!\n",
  58. Status);
  59. goto FnExit;
  60. }
  61. ClRtlLogPrint(LOG_NOISE,
  62. "[CP] CppDepositCheckpoint checkpointing data to file %1!ws!\n",
  63. FileName);
  64. //
  65. // Create the directory.
  66. //
  67. if (!QfsCreateDirectory(DirectoryName, NULL))
  68. {
  69. Status = GetLastError();
  70. if (Status != ERROR_ALREADY_EXISTS)
  71. {
  72. ClRtlLogPrint(LOG_CRITICAL,
  73. "[CP] CppDepositCheckpoint unable to create directory %1!ws!, error %2!d!\n",
  74. DirectoryName,
  75. Status);
  76. goto FnExit;
  77. }
  78. else
  79. {
  80. //the directory exists, set Status to ERROR_SUCCESS
  81. Status = ERROR_SUCCESS;
  82. }
  83. }
  84. else
  85. {
  86. //
  87. // The directory was newly created. Put the appropriate ACL on it
  88. // so that only ADMINs can read it.
  89. //
  90. Status = QfsSetFileSecurityInfo(DirectoryName,
  91. GENERIC_ALL,
  92. GENERIC_ALL,
  93. 0);
  94. if (Status != ERROR_SUCCESS)
  95. {
  96. ClRtlLogPrint(LOG_CRITICAL,
  97. "[CP] CppDepositCheckpoint- unable to set ACL on directory %1!ws!, error %2!d!\n",
  98. DirectoryName,
  99. Status);
  100. goto FnExit;
  101. }
  102. }
  103. //
  104. // Pull the checkpoint data file across RPC
  105. //
  106. Status = DmPullFile(FileName, CheckpointData);
  107. if (Status != ERROR_SUCCESS) {
  108. ClRtlLogPrint(LOG_CRITICAL,
  109. "[CP] CppDepositCheckpoint - DmPullFile %1!ws! failed %2!d!\n",
  110. FileName,
  111. Status);
  112. }
  113. FnExit:
  114. RELEASE_LOCK(gQuoLock);
  115. //clean up
  116. if (DirectoryName) LocalFree(DirectoryName);
  117. if (FileName) LocalFree(FileName);
  118. //
  119. // Adjust the return status if the quorum volume is truly offline and that is why this
  120. // call failed.
  121. //
  122. if ( ( Status != ERROR_SUCCESS ) && ( CppIsQuorumVolumeOffline() == TRUE ) ) Status = ERROR_NOT_READY;
  123. //At this point, CppDepositCheckpoint should either
  124. //a) throw the error code as an exception, or
  125. //b) drain the [in] pipe and then return the error code normally
  126. //but if it returns without draining the pipe, and the RPC runtime throws
  127. //the pipe-discipline exception.
  128. if (Status != ERROR_SUCCESS)
  129. RpcRaiseException(Status);
  130. return(Status);
  131. }
  132. error_status_t
  133. s_CpDepositCheckpoint(
  134. handle_t IDL_handle,
  135. LPCWSTR ResourceId,
  136. DWORD dwCheckpointId,
  137. BYTE_PIPE CheckpointData
  138. )
  139. /*++
  140. Routine Description:
  141. Server side RPC to allow other nodes to checkpoint data to the
  142. quorum disk.
  143. Arguments:
  144. IDL_handle - RPC binding handle, not used.
  145. ResourceId - Name of the resource whose data is being checkpointed
  146. dwCheckpointId - Unique identifier of the checkpoint
  147. CheckpointData - pipe through which checkpoint data can be retrieved.
  148. Return Value:
  149. ERROR_SUCCESS if successful
  150. Win32 error code otherwise
  151. --*/
  152. {
  153. CP_VALIDATE_ID_STRING ( ResourceId );
  154. return CppDepositCheckpoint(IDL_handle,
  155. ResourceId,
  156. dwCheckpointId,
  157. CheckpointData,
  158. FALSE
  159. );
  160. }
  161. error_status_t
  162. s_CpDepositCryptoCheckpoint(
  163. handle_t IDL_handle,
  164. LPCWSTR ResourceId,
  165. DWORD dwCheckpointId,
  166. BYTE_PIPE CheckpointData
  167. )
  168. /*++
  169. Routine Description:
  170. Server side RPC to allow other nodes to checkpoint data to the
  171. quorum disk.
  172. Arguments:
  173. IDL_handle - RPC binding handle, not used.
  174. ResourceId - Name of the resource whose data is being checkpointed
  175. dwCheckpointId - Unique identifier of the checkpoint
  176. CheckpointData - pipe through which checkpoint data can be retrieved.
  177. Return Value:
  178. ERROR_SUCCESS if successful
  179. Win32 error code otherwise
  180. --*/
  181. {
  182. CP_VALIDATE_ID_STRING ( ResourceId );
  183. return CppDepositCheckpoint(IDL_handle,
  184. ResourceId,
  185. dwCheckpointId,
  186. CheckpointData,
  187. TRUE
  188. );
  189. }
  190. error_status_t
  191. CppRetrieveCheckpoint(
  192. handle_t IDL_handle,
  193. LPCWSTR ResourceId,
  194. DWORD dwCheckpointId,
  195. BOOLEAN fCryptoCheckpoint,
  196. BYTE_PIPE CheckpointData
  197. )
  198. /*++
  199. Routine Description:
  200. Server side RPC through which data checkpointed to the quorum disk
  201. can be retrieved by other nodes.
  202. Arguments:
  203. IDL_handle - RPC binding handle, not used.
  204. ResourceId - Name of the resource whose checkpoint data is to be retrieved
  205. dwCheckpointId - Unique identifier of the checkpoint
  206. fCryptoCheckpoint - Indicates if the checkpoint is a crypto checkpoint
  207. CheckpointData - pipe through which checkpoint data should be sent
  208. Return Value:
  209. ERROR_SUCCESS if successful
  210. Win32 error code otherwise
  211. --*/
  212. {
  213. DWORD Status;
  214. LPWSTR FileName=NULL;
  215. HANDLE hFile;
  216. BOOL Success;
  217. PFM_RESOURCE Resource;
  218. ACQUIRE_SHARED_LOCK(gQuoLock);
  219. Resource = OmReferenceObjectById(ObjectTypeResource, ResourceId);
  220. if (Resource == NULL) {
  221. Status = ERROR_FILE_NOT_FOUND;
  222. goto FnExit;
  223. }
  224. Status = CppGetCheckpointFile(Resource,
  225. dwCheckpointId,
  226. NULL,
  227. &FileName,
  228. NULL,
  229. fCryptoCheckpoint);
  230. OmDereferenceObject(Resource);
  231. if (Status != ERROR_SUCCESS) {
  232. ClRtlLogPrint(LOG_CRITICAL,
  233. "[CP] CppRetrieveCheckpoint - CppGetCheckpointFile failed %1!d!\n",
  234. Status);
  235. goto FnExit;
  236. }
  237. ClRtlLogPrint(LOG_NOISE,
  238. "[CP] CppRetrieveCheckpoint retrieving data from file %1!ws!\n",
  239. FileName);
  240. //
  241. // Push the checkpoint data file across RPC
  242. //
  243. Status = DmPushFile(FileName, CheckpointData, TRUE); // TRUE == encrypt the data on the wire
  244. if (Status != ERROR_SUCCESS) {
  245. ClRtlLogPrint(LOG_CRITICAL,
  246. "[CP] CppRetrieveCheckpoint - DmPushFile %1!ws! failed %2!d!\n",
  247. FileName,
  248. Status);
  249. }
  250. FnExit:
  251. RELEASE_LOCK(gQuoLock);
  252. //cleanup
  253. if (FileName) LocalFree(FileName);
  254. //
  255. // Adjust the return status if the quorum volume is truly offline and that is why this
  256. // call failed.
  257. //
  258. if ( ( Status != ERROR_SUCCESS ) && ( CppIsQuorumVolumeOffline() == TRUE ) ) Status = ERROR_NOT_READY;
  259. return(Status);
  260. }
  261. error_status_t
  262. s_CpRetrieveCheckpoint(
  263. handle_t IDL_handle,
  264. LPCWSTR ResourceId,
  265. DWORD dwCheckpointId,
  266. BYTE_PIPE CheckpointData
  267. )
  268. /*++
  269. Routine Description:
  270. Server side RPC through which data checkpointed to the quorum disk
  271. can be retrieved by other nodes.
  272. Arguments:
  273. IDL_handle - RPC binding handle, not used.
  274. ResourceId - Name of the resource whose checkpoint data is to be retrieved
  275. dwCheckpointId - Unique identifier of the checkpoint
  276. CheckpointData - pipe through which checkpoint data should be sent
  277. Return Value:
  278. ERROR_SUCCESS if successful
  279. Win32 error code otherwise
  280. --*/
  281. {
  282. CP_VALIDATE_ID_STRING ( ResourceId );
  283. return CppRetrieveCheckpoint(IDL_handle,
  284. ResourceId,
  285. dwCheckpointId,
  286. FALSE,
  287. CheckpointData
  288. );
  289. }
  290. error_status_t
  291. s_CpRetrieveCryptoCheckpoint(
  292. handle_t IDL_handle,
  293. LPCWSTR ResourceId,
  294. DWORD dwCheckpointId,
  295. BYTE_PIPE CheckpointData
  296. )
  297. /*++
  298. Routine Description:
  299. Server side RPC through which data checkpointed to the quorum disk
  300. can be retrieved by other nodes.
  301. Arguments:
  302. IDL_handle - RPC binding handle, not used.
  303. ResourceId - Name of the resource whose checkpoint data is to be retrieved
  304. dwCheckpointId - Unique identifier of the checkpoint
  305. CheckpointData - pipe through which checkpoint data should be sent
  306. Return Value:
  307. ERROR_SUCCESS if successful
  308. Win32 error code otherwise
  309. --*/
  310. {
  311. CP_VALIDATE_ID_STRING ( ResourceId );
  312. return CppRetrieveCheckpoint(IDL_handle,
  313. ResourceId,
  314. dwCheckpointId,
  315. TRUE,
  316. CheckpointData
  317. );
  318. }
  319. error_status_t
  320. CppDeleteCheckpoint(
  321. handle_t IDL_handle,
  322. LPCWSTR ResourceId,
  323. DWORD dwCheckpointId,
  324. LPCWSTR lpszQuorumPath,
  325. BOOL fCryptoCheckpoint
  326. )
  327. /*++
  328. Routine Description:
  329. Server side RPC through which the checkpoint file corresponding to a
  330. given checkpointid for a resource is deleted.
  331. Arguments:
  332. IDL_handle - RPC binding handle, not used.
  333. ResourceId - Name of the resource whose checkpoint file is to be deleted.
  334. dwCheckpointId - Unique identifier of the checkpoint. If 0, all checkpoints
  335. must be deleted.
  336. lpszQuorumPath - The path to the cluster files from where these files must
  337. be deleted.
  338. fCryptoCheckpoint - Indicates if the checkpoint is a crypto checkpoint
  339. Return Value:
  340. ERROR_SUCCESS if successful
  341. Win32 error code otherwise
  342. --*/
  343. {
  344. DWORD Status;
  345. PFM_RESOURCE Resource = NULL;
  346. Resource = OmReferenceObjectById(ObjectTypeResource, ResourceId);
  347. if (Resource == NULL) {
  348. Status = ERROR_FILE_NOT_FOUND;
  349. goto FnExit;
  350. }
  351. if (fCryptoCheckpoint) {
  352. Status = CpckDeleteCheckpointFile(Resource, dwCheckpointId, lpszQuorumPath);
  353. } else {
  354. Status = CppDeleteCheckpointFile(Resource, dwCheckpointId, lpszQuorumPath);
  355. }
  356. if (Status != ERROR_SUCCESS)
  357. {
  358. goto FnExit;
  359. }
  360. FnExit:
  361. if (Resource) OmDereferenceObject(Resource);
  362. return(Status);
  363. }
  364. error_status_t
  365. s_CpDeleteCheckpoint(
  366. handle_t IDL_handle,
  367. LPCWSTR ResourceId,
  368. DWORD dwCheckpointId,
  369. LPCWSTR lpszQuorumPath
  370. )
  371. /*++
  372. Routine Description:
  373. Server side RPC through which the checkpoint file corresponding to a
  374. given checkpointid for a resource is deleted.
  375. Arguments:
  376. IDL_handle - RPC binding handle, not used.
  377. ResourceId - Name of the resource whose checkpoint file is to be deleted.
  378. dwCheckpointId - Unique identifier of the checkpoint. If 0, all checkpoints
  379. must be deleted.
  380. lpszQuorumPath - The path to the cluster files from where these files must
  381. be deleted.
  382. Return Value:
  383. ERROR_SUCCESS if successful
  384. Win32 error code otherwise
  385. --*/
  386. {
  387. CP_VALIDATE_ID_STRING ( ResourceId );
  388. return CppDeleteCheckpoint(IDL_handle,
  389. ResourceId,
  390. dwCheckpointId,
  391. lpszQuorumPath,
  392. FALSE);
  393. }
  394. error_status_t
  395. s_CpDeleteCryptoCheckpoint(
  396. handle_t IDL_handle,
  397. LPCWSTR ResourceId,
  398. DWORD dwCheckpointId,
  399. LPCWSTR lpszQuorumPath
  400. )
  401. /*++
  402. Routine Description:
  403. Server side RPC through which the crypto checkpoint file corresponding to a
  404. given checkpointid for a resource is deleted.
  405. Arguments:
  406. IDL_handle - RPC binding handle, not used.
  407. ResourceId - Name of the resource whose checkpoint file is to be deleted.
  408. dwCheckpointId - Unique identifier of the checkpoint. If 0, all checkpoints
  409. must be deleted.
  410. lpszQuorumPath - The path to the cluster files from where these files must
  411. be deleted.
  412. Return Value:
  413. ERROR_SUCCESS if successful
  414. Win32 error code otherwise
  415. --*/
  416. {
  417. CP_VALIDATE_ID_STRING ( ResourceId );
  418. return CppDeleteCheckpoint(IDL_handle,
  419. ResourceId,
  420. dwCheckpointId,
  421. lpszQuorumPath,
  422. TRUE);
  423. }