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.

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