|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
file.c
Abstract:
General file-related functions.
Author:
Souren Aghajanyan 12-Jul-2001
Revision History:
sourenag 12-Jul-2001 RenameOperation supports function
--*/
#include "pch.h"
#define UNDO_FILE_NAME L"UNDO_GUIMODE.TXT"
BOOL pRenameOnRestartOfGuiMode ( IN OUT HANDLE *UndoHandlePtr, OPTIONAL IN PCWSTR PathName, IN PCWSTR PathNameNew OPTIONAL ) { DWORD dontCare; BOOL result; static WCHAR undoFilePath[MAX_PATH]; BYTE signUnicode[] = {0xff, 0xfe}; DWORD filePos; HANDLE undoHandle;
if (!PathName) { MYASSERT (FALSE); return FALSE; }
if (!UndoHandlePtr || !(*UndoHandlePtr)) {
if (!undoFilePath[0]) { //
// Create the path to the journal file
//
wsprintfW (undoFilePath, L"%s\\" UNDO_FILE_NAME, g_System32Dir); }
//
// Open the journal file
//
undoHandle = CreateFileW ( undoFilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if (undoHandle == INVALID_HANDLE_VALUE) { LOG ((LOG_ERROR, "Failed to open journal file %s", undoFilePath)); return FALSE; }
MYASSERT (undoHandle); // never NULL
} else { undoHandle = *UndoHandlePtr; }
//
// Move to the end of the journal, and if the journal is empty, write the UNICODE header
//
filePos = SetFilePointer (undoHandle, 0, NULL, FILE_END);
if (!filePos) { result = WriteFile (undoHandle, signUnicode, sizeof(signUnicode), &dontCare, NULL); } else { result = TRUE; }
//
// Output the move or delete operation
//
result = result && WriteFile ( undoHandle, L"\\??\\", 8, &dontCare, NULL );
result = result && WriteFile ( undoHandle, PathName, ByteCountW (PathName), &dontCare, NULL );
result = result && WriteFile ( undoHandle, L"\r\n", 4, &dontCare, NULL );
if (PathNameNew) { result = result && WriteFile ( undoHandle, L"\\??\\", 8, &dontCare, NULL );
result = result && WriteFile ( undoHandle, PathNameNew, ByteCountW (PathNameNew), &dontCare, NULL ); }
result = result && WriteFile ( undoHandle, L"\r\n", 4, &dontCare, NULL );
if (!result) { //
// On failure, log an error and truncate the file
//
LOGW (( LOG_ERROR, "Failed to record move in restart journal: %s to %s", PathName, PathNameNew ));
SetFilePointer (undoHandle, filePos, NULL, FILE_BEGIN); SetEndOfFile (undoHandle); }
if (UndoHandlePtr) {
if (!(*UndoHandlePtr)) { //
// If caller did not pass in handle, then we opened it.
//
if (result) { *UndoHandlePtr = undoHandle; // give ownership to caller
} else { FlushFileBuffers (undoHandle); CloseHandle (undoHandle); // fail; don't leak handle
} }
} else { //
// Caller wants to record just one move
//
FlushFileBuffers (undoHandle); CloseHandle (undoHandle); }
return result; }
BOOL RenameOnRestartOfGuiMode ( IN PCWSTR PathName, IN PCWSTR PathNameNew OPTIONAL ) { return pRenameOnRestartOfGuiMode (NULL, PathName, PathNameNew); }
BOOL RenameListOnRestartOfGuiMode ( IN PGROWLIST SourceList, IN PGROWLIST DestList ) { UINT u; UINT count; PCWSTR source; PCWSTR dest; HANDLE journal = NULL;
count = GrowListGetSize (SourceList); for (u = 0 ; u < count ; u++) {
source = GrowListGetString (SourceList, u); if (!source) { continue; }
dest = GrowListGetString (DestList, u);
if (!pRenameOnRestartOfGuiMode (&journal, source, dest)) { break; } }
if (journal) { FlushFileBuffers (journal); CloseHandle (journal); }
return u == count; }
|