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.

237 lines
5.6 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. file.c
  5. Abstract:
  6. General file-related functions.
  7. Author:
  8. Souren Aghajanyan 12-Jul-2001
  9. Revision History:
  10. sourenag 12-Jul-2001 RenameOperation supports function
  11. --*/
  12. #include "pch.h"
  13. #include "commonntp.h"
  14. #define UNDO_FILE_NAME L"UNDO_GUIMODE.TXT"
  15. BOOL
  16. pRenameOnRestartOfGuiMode (
  17. IN OUT HANDLE *UndoHandlePtr, OPTIONAL
  18. IN PCWSTR PathName,
  19. IN PCWSTR PathNameNew OPTIONAL
  20. )
  21. {
  22. DWORD dontCare;
  23. BOOL result;
  24. static WCHAR undoFilePath[MAX_PATH];
  25. BYTE signUnicode[] = {0xff, 0xfe};
  26. DWORD filePos;
  27. HANDLE undoHandle;
  28. if (!PathName) {
  29. MYASSERT (FALSE);
  30. return FALSE;
  31. }
  32. if (!UndoHandlePtr || !(*UndoHandlePtr)) {
  33. if (!undoFilePath[0]) {
  34. //
  35. // Create the path to the journal file
  36. //
  37. wsprintfW (undoFilePath, L"%s\\" UNDO_FILE_NAME, g_System32Dir);
  38. }
  39. //
  40. // Open the journal file
  41. //
  42. undoHandle = CreateFileW (
  43. undoFilePath,
  44. GENERIC_WRITE,
  45. FILE_SHARE_READ,
  46. NULL,
  47. OPEN_ALWAYS,
  48. FILE_ATTRIBUTE_NORMAL,
  49. NULL
  50. );
  51. if (undoHandle == INVALID_HANDLE_VALUE) {
  52. LOG ((LOG_ERROR, "Failed to open journal file %s", undoFilePath));
  53. return FALSE;
  54. }
  55. MYASSERT (undoHandle); // never NULL
  56. } else {
  57. undoHandle = *UndoHandlePtr;
  58. }
  59. //
  60. // Move to the end of the journal, and if the journal is empty, write the UNICODE header
  61. //
  62. filePos = SetFilePointer (undoHandle, 0, NULL, FILE_END);
  63. if (!filePos) {
  64. result = WriteFile (undoHandle, signUnicode, sizeof(signUnicode), &dontCare, NULL);
  65. } else {
  66. result = TRUE;
  67. }
  68. //
  69. // Output the move or delete operation
  70. //
  71. result = result && WriteFile (
  72. undoHandle,
  73. L"\\??\\",
  74. 8,
  75. &dontCare,
  76. NULL
  77. );
  78. result = result && WriteFile (
  79. undoHandle,
  80. PathName,
  81. ByteCountW (PathName),
  82. &dontCare,
  83. NULL
  84. );
  85. result = result && WriteFile (
  86. undoHandle,
  87. L"\r\n",
  88. 4,
  89. &dontCare,
  90. NULL
  91. );
  92. if (PathNameNew) {
  93. result = result && WriteFile (
  94. undoHandle,
  95. L"\\??\\",
  96. 8,
  97. &dontCare,
  98. NULL
  99. );
  100. result = result && WriteFile (
  101. undoHandle,
  102. PathNameNew,
  103. ByteCountW (PathNameNew),
  104. &dontCare,
  105. NULL
  106. );
  107. }
  108. result = result && WriteFile (
  109. undoHandle,
  110. L"\r\n",
  111. 4,
  112. &dontCare,
  113. NULL
  114. );
  115. if (!result) {
  116. //
  117. // On failure, log an error and truncate the file
  118. //
  119. LOGW ((
  120. LOG_ERROR,
  121. "Failed to record move in restart journal: %s to %s",
  122. PathName,
  123. PathNameNew
  124. ));
  125. SetFilePointer (undoHandle, filePos, NULL, FILE_BEGIN);
  126. SetEndOfFile (undoHandle);
  127. }
  128. if (UndoHandlePtr) {
  129. if (!(*UndoHandlePtr)) {
  130. //
  131. // If caller did not pass in handle, then we opened it.
  132. //
  133. if (result) {
  134. *UndoHandlePtr = undoHandle; // give ownership to caller
  135. } else {
  136. FlushFileBuffers (undoHandle);
  137. CloseHandle (undoHandle); // fail; don't leak handle
  138. }
  139. }
  140. } else {
  141. //
  142. // Caller wants to record just one move
  143. //
  144. FlushFileBuffers (undoHandle);
  145. CloseHandle (undoHandle);
  146. }
  147. return result;
  148. }
  149. BOOL
  150. RenameOnRestartOfGuiMode (
  151. IN PCWSTR PathName,
  152. IN PCWSTR PathNameNew OPTIONAL
  153. )
  154. {
  155. return pRenameOnRestartOfGuiMode (NULL, PathName, PathNameNew);
  156. }
  157. BOOL
  158. RenameListOnRestartOfGuiMode (
  159. IN PGROWLIST SourceList,
  160. IN PGROWLIST DestList
  161. )
  162. {
  163. UINT u;
  164. UINT count;
  165. PCWSTR source;
  166. PCWSTR dest;
  167. HANDLE journal = NULL;
  168. count = GrowListGetSize (SourceList);
  169. for (u = 0 ; u < count ; u++) {
  170. source = GrowListGetString (SourceList, u);
  171. if (!source) {
  172. continue;
  173. }
  174. dest = GrowListGetString (DestList, u);
  175. if (!pRenameOnRestartOfGuiMode (&journal, source, dest)) {
  176. break;
  177. }
  178. }
  179. if (journal) {
  180. FlushFileBuffers (journal);
  181. CloseHandle (journal);
  182. }
  183. return u == count;
  184. }