Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

548 lines
17 KiB

#include "precomp.h"
/************************************************************************/
/* */
/* Windows Cardfile - Written by Mark Cliggett */
/* (c) Copyright Microsoft Corp. 1985, 1994 - All Rights Reserved */
/* */
/************************************************************************/
int fReadOnly = FALSE;
/* win.ini string for fValidate value */
TCHAR szValidateFileWrite[] = TEXT("ValidateFileWrite");
BOOL fValidate = TRUE; /* TRUE if validating on save */
NOEXPORT BOOL ValidCardFile (TCHAR szFile[], WORD fType);
NOEXPORT BOOL FileHasTextOnly (HANDLE hCards, HANDLE fhMain, HANDLE fhTemp);
/*
* Calls GetSaveFileName(), the COMMDLG function.
* If the filename returned is invalid, it prompts again.
* If the given filename exists, it asks for overwrite permission.
* return FALSE if dlg cancelled, TRUE otherwise.
*
* also returns requested file type to save if function TRUE.
*/
BOOL MyGetSaveFileName (TCHAR *szFile, WORD * pfType)
{
BOOL fResult;
HANDLE fh;
while (TRUE)
{
OFN.lpstrDefExt = szFileExtension;
OFN.lpstrFilter = szFilterSpec;
OFN.lpstrCustomFilter = szCustFilterSpec;
lstrcpy (szFile, FileFromPath (CurIFile));
OFN.lpstrFile = szFile;
OFN.lpstrInitialDir = szLastDir;
OFN.lpstrTitle = szSaveCaption;
OFN.lpfnHook = (LPOFNHOOKPROC) MakeProcInstance(HookProc, hIndexInstance);
OFN.Flags = OFN_PATHMUSTEXIST | OFN_ENABLEHOOK|OFN_OVERWRITEPROMPT;
/* set reasonable default filter for file type */
OFN.nFilterIndex = fFileType;
fValidDB = fValidate;
fInSaveAsDlg = TRUE;
LockData (0);
fResult = GetSaveFileName (&OFN);
UnlockData (0);
fInSaveAsDlg = FALSE;
FreeProcInstance (OFN.lpfnHook);
if (!fResult)
return FALSE; /* SaveFile Dlg cancelled */
if (OFN.nFilterIndex == ANSI_FILE)
*pfType = ANSI_FILE;
else if (OFN.nFilterIndex == OLD_FORMAT)
*pfType = OLD_FORMAT;
else
*pfType = UNICODE_FILE;
fValidate = fValidDB;
if ((fh = MyOpenFile (szFile, NULL, OF_EXIST)) == INVALID_HANDLE_VALUE)
{
DWORD err = GetLastError();
if (err == ERROR_ACCESS_DENIED)
{
BuildAndDisplayMsg(E_FILECANTWRITE, szFile);
continue;
}
return TRUE;
}
/* New name is same as current file name, share won't let us open
* the file again, so we shouldn't even try an open */
if (lstrcmpi (szFile, CurIFile) == 0)
return TRUE;
fh = MyOpenFile (szFile, NULL, OF_READWRITE);
if (fh == INVALID_HANDLE_VALUE) /* file exists and it is read only */
{
DWORD err = GetLastError();
if (err == ERROR_ACCESS_DENIED)
{
BuildAndDisplayMsg(E_FILECANTWRITE, szFile);
continue;
}
return TRUE;
}
else
MyCloseFile (fh);
return TRUE; /* OK to overwrite, return filename */
}
}
NOEXPORT BOOL NEAR WriteCardfileFailed (
int errorID,
HANDLE fhDest,
HANDLE fhTemp,
TCHAR *DestFile,
LPCARDHEADER Cards)
{
Hourglass (FALSE);
MyCloseFile (fhDest);
MyCloseFile (fhTemp);
if (Cards)
GlobalUnlock (hCards);
Fdelete (DestFile);
return IndexOkError (errorID);
}
/* WriteCardFile
*
*/
int WriteCardFile (TCHAR *pName, WORD fType)
{
WORD i;
INT nChars;
int fSameFile;
CARDHEADER CardHeader;
BOOL fOld;
LPCARDHEADER Cards = NULL;
HANDLE fh;
INT fSourceType; // type of each line (UNICODE_FILE,ANSI_FILE etc)
/* destination file vars */
TCHAR DestFile[PATHMAX];
WORD wCards;
HANDLE fhDest;
DWORD oHdr; /* offset to Hdr in fhDest */
DWORD oCard; /* offset to Card in fhDest */
HANDLE fhTemp; /* temp file containing modified cards */
// validate file types being passed
if( (fType!=UNICODE_FILE) && (fType!=ANSI_FILE) && (fType!=OLD_FORMAT))
{
OutputDebugString(TEXT("Bad File type\n"));
return( BuildAndDisplayMsg( E_FILEUPDATEFAILED, pName ) );
}
/*
* Set destination file name.
* If saving to source file, an intermediate temp file is needed
* else can save directly to the given file.
*/
if (fSameFile = !lstrcmp (pName, CurIFile))
{
TCHAR szTemp[PATHMAX];
GetTempPath (PATHMAX - 1, szTemp);
if (!GetTempFileName (szTemp, szFileExtension, 0, DestFile))
return BuildAndDisplayMsg (ECANTMAKEFILE, pName);
}
else
lstrcpy (DestFile, pName);
/* Open Destination file */
fhDest = MyOpenFile (DestFile, NULL, OF_SHARE_DENY_WRITE | OF_READWRITE | OF_CREATE);
/* Open the temp file containing modified/new cards */
fhTemp = MyOpenFile (TempFile, NULL, OF_SHARE_EXCLUSIVE | OF_READWRITE);
if (fhDest == INVALID_HANDLE_VALUE || fhTemp == INVALID_HANDLE_VALUE)
{
TCHAR szFormat[100];
TCHAR szMsg[200];
/* close valid file handles */
if (fhTemp != INVALID_HANDLE_VALUE)
MyCloseFile (fhTemp);
if (fhDest != INVALID_HANDLE_VALUE)
MyCloseFile (fhDest);
LoadString (hIndexInstance, E_FILESAVE, szFormat, CharSizeOf(szFormat));
wsprintf (szMsg, szFormat, pName,
(fhDest == INVALID_HANDLE_VALUE) ? DestFile : TempFile);
MessageBox (hIndexWnd, szMsg, szNote, MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if ((fSameFile && fReadOnly) || /* saving to same file which was read in as read only */
fNoTempFile || /* no temp file ? */
MyFileSeek (fhDest, 0L, 0) == -1) /* truncate destination file */
{
CloseHandle (fhDest);
CloseHandle (fhTemp);
return BuildAndDisplayMsg (ECANTMAKEFILE, pName);
}
Hourglass (TRUE);
MyByteWriteFile (fhDest, TEXT(""), 0);
/* Write cardfile identifier(DKO is Unicode and RRG is ANSI) and
* number of cards */
if (fType == UNICODE_FILE)
{
if (!MyByteWriteFile (fhDest, chDKO, 3))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
}
else if (fType == ANSI_FILE)
{
if (!MyByteWriteFile (fhDest, chRRG, 3))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
}
else if (fType == OLD_FORMAT)
{
if (!MyByteWriteFile (fhDest, chMGC, 3))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
}
if (fType != OLD_FORMAT && !MyByteWriteFile (fhDest, &idObjectMax, sizeof(DWORD)))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
wCards = (WORD)cCards;
if (!MyByteWriteFile (fhDest, &wCards, sizeof(WORD)))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
if (fType == UNICODE_FILE)
oCard = MyFileSeek (fhDest, 0L, 1) +
(DWORD)((WORD)cCards * (WORD)SIZEOFCARDHEADERW);
else
oCard = MyFileSeek (fhDest, 0L, 1) +
(DWORD)((WORD)cCards * (WORD)SIZEOFCARDHEADERA);
/* lock down the card headers */
Cards = (LPCARDHEADER) GlobalLock (hCards);
for (i = 0; i < cCards; i++)
{
/* write out card hdr */
CardHeader = Cards[i];
CardHeader.flags &= (~FTMPFILE); /* no more in the temp file */
CardHeader.lfData = oCard; /* set new offset */
if (!MyByteWriteFile (fhDest, &(CardHeader.reserved), 6))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
if (!MyByteWriteFile (fhDest, &(CardHeader.lfData), 4))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
if (!MyByteWriteFile (fhDest, &(CardHeader.flags), 1))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
if (fType == UNICODE_FILE)
{
if (!MyByteWriteFile (fhDest, CardHeader.line, ByteCountOf(LINELENGTH+1)))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
}
else
{
if (!MyAnsiWriteFile (fhDest, CP_ACP, CardHeader.line, LINELENGTH+1))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
}
oHdr = MyFileSeek (fhDest, 0L, 1); /* store offset for the next hdr */
/* pick up card data from src or temp file */
if (Cards[i].flags & FTMPFILE)
{
fSourceType= UNICODE_FILE; // the temp file is always UNICODE
fh = fhTemp;
}
else
{
fSourceType= fFileType; // original source never changes
fh = fhMain;
}
/* If we're in the compatibility zone, punt */
fOld = (fSourceType == OLD_FORMAT);
/* read card data and write it out */
if (MyFileSeek (fh, Cards[i].lfData, 0) == -1 ||
!PicRead (&CurCard, fh, !fOLE || fOld))
{
#ifdef WIN32
CurIFile[2] = TEXT('\0') ;
return WriteCardfileFailed (
(GetDriveType (CurIFile) == DRIVE_REMOVABLE)
? E_FLOPPY_WITH_SOURCE_REMOVED
: E_FAILED_TO_READ_CARD,
fhDest, fhTemp, DestFile, Cards);
#else
return WriteCardfileFailed (
(GetDriveType (CurIFile[0] - TEXT('A')) == DRIVE_REMOVABLE)
? E_FLOPPY_WITH_SOURCE_REMOVED
: E_FAILED_TO_READ_CARD,
fhDest, fhTemp, DestFile, Cards);
#endif
}
if (MyFileSeek (fhDest, oCard, 0) == -1 ||
!PicWrite (&CurCard, fhDest, fType == OLD_FORMAT))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
if (CurCard.lpObject)
PicDelete (&CurCard);
/* read text size and text, write it out */
if ((nChars = TextRead (fh, szText, fSourceType)) < 0 ||
!MyByteWriteFile (fhDest, &nChars, (DWORD) sizeof(WORD)))
{
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
}
if (fType == UNICODE_FILE)
{
if (!MyByteWriteFile (fhDest, szText, ByteCountOf(nChars)))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
}
else
{
if (!MyAnsiWriteFile (fhDest, CP_ACP, szText, nChars))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
}
oCard = MyFileSeek (fhDest, 0L, 1); /* store offset for the next card data */
MyFileSeek (fhDest, oHdr, 0); /* ready to read the next hdr */
}
MyFileSeek (fhDest, 3, 0); /* put in correct value of idObjectMax */
if (fType != OLD_FORMAT && !MyByteWriteFile (fhDest, &idObjectMax, sizeof(DWORD)))
return WriteCardfileFailed (EDISKFULLFILE, fhDest, fhTemp, DestFile, Cards);
MyCloseFile (fhDest); /* close destination file */
/* check if destination file is a valid cardfile */
/* Cardfile corruption problem:
* Cardfile occasionally writes out corrupted files.
* During File.Save:
* If the file is corrupted then the rename is skipped, preserving the
* original source file from being updated to a corrupted one.
*
* During File.SaveAs:
* If it is corrupted, the file is deleted.
*/
if (!ValidCardFile (DestFile, fType))
{
Fdelete (DestFile); /* no use creating a corrupted file */
if (fSameFile)
BuildAndDisplayMsg (E_FILEUPDATEFAILED, CurIFile);
else
BuildAndDisplayMsg (E_FILEWRITEFAILED, DestFile);
Hourglass (FALSE);
GlobalUnlock (hCards);
return TRUE; /* avoid putting up the SaveAs dialog */
}
if (fhMain != INVALID_HANDLE_VALUE) /* close source file if any */
MyCloseFile (fhMain);
if (fSameFile)
{
TCHAR HackBuffer[PATHMAX];
TCHAR HackDest[PATHMAX];
MyCloseFile (fhTemp);
lstrcpy (HackDest, DestFile);
lstrcpy (HackBuffer, pName);
if (Fdelete (HackBuffer))
{
Fdelete (HackDest); /* remove temp file */
BuildAndDisplayMsg (E_FILEWRITEFAILED, CurIFile); /* delete old src file */
fhMain = MyOpenFile (CurIFile, NULL, OF_SHARE_DENY_WRITE | OF_READ);
return FALSE;
}
// We MUST copy the file and delete the source because rename does not
// work if the user has their TMP path set to another drive!!
if (CopyFile (HackDest, HackBuffer, TRUE)) // File if already exists
DeleteFile (HackDest);
}
else
{
MyFileSeek (fhTemp, 0L, 0); /* truncate temp file and close it */
MyByteWriteFile (fhTemp, TEXT(""), 0);
MyCloseFile (fhTemp);
}
fReadOnly = FALSE; /* we just wrote out the new file */
fhMain = MyOpenFile (pName, NULL, OF_SHARE_DENY_WRITE | OF_READ);
lstrcpy (CurIFile, pName);
/* check cardfile signature */
if (!CheckCardfileSignature (fhMain, &fType))
{
MyCloseFile (fhMain);
fhMain = INVALID_HANDLE_VALUE;
return FALSE;
}
/* read the number of cards in the file */
MyByteReadFile (fhMain, &wCards, sizeof(WORD));
cCards = (INT) wCards;
#if !defined WIN32
for (i = 0; i < cCards; ++i)
{
MyByteReadFile (fhMain, &CardHeader, sizeof(CARDHEADER));
Cards[i] = CardHeader;
}
#else
// Lack of packing on WIN32...
for (i = 0; i < cCards; i++)
{
MyByteReadFile (fhMain, &(CardHeader.reserved), 6);
MyByteReadFile (fhMain, &(CardHeader.lfData), 4);
MyByteReadFile (fhMain, &(CardHeader.flags), 1);
if (fType == UNICODE_FILE)
MyByteReadFile (fhMain, CardHeader.line, ByteCountOf(LINELENGTH+1));
else
MyAnsiReadFile (fhMain, CP_ACP, CardHeader.line, LINELENGTH+1);
Cards[i] = CardHeader;
}
#endif
fFileDirty = FALSE;
fFileType = fType;
GlobalUnlock (hCards);
Hourglass (FALSE);
return TRUE;
}
NOEXPORT BOOL ValidCardfileFailed(
HANDLE fh)
{
MyCloseFile (fh);
return FALSE;
}
/*
* Returns TRUE if PicRead is successful on all the cards in the file
* FALSE otherwise.
*/
NOEXPORT BOOL NEAR ValidCardFile(
TCHAR szFile[],
WORD fType)
{
int i;
HANDLE fh;
BYTE Signature[3];
WORD nCards;
DWORD nObjectMax;
DWORD cBytes;
HANDLE hHdrs;
CARD Card;
LPCARDHEADER Cards;
if (!fValidate)
return TRUE;
/* open file */
fh = MyOpenFile (szFile, NULL, OF_READ | OF_SHARE_DENY_WRITE);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
/* try to read the cardfile */
/* read the cardfile signature */
MyByteReadFile (fh, Signature, 3);
if ((fType == OLD_FORMAT && memcmp (Signature, chMGC, 3)) ||
(fType == ANSI_FILE && memcmp (Signature, chRRG, 3)) ||
(fType == UNICODE_FILE && memcmp (Signature, chDKO, 3)))
return ValidCardfileFailed(fh);
if (fType != OLD_FORMAT)
{
/* read in the max id */
MyByteReadFile(fh, &nObjectMax, sizeof(DWORD));
if (nObjectMax != idObjectMax)
return ValidCardfileFailed(fh);
}
/* read the number of cards in the file */
MyByteReadFile (fh, &nCards, sizeof(WORD));
cBytes = mylmul(nCards, SIZEOFCARDHEADER);
if (nCards != cCards ||
#if !defined (WIN32)
cBytes >= 0x0000FFFF ||
#endif
!(hHdrs = GlobalAlloc(GHND, (DWORD)(nCards * sizeof(CARDHEADER)))) ||
!(Cards = (LPCARDHEADER) GlobalLock(hHdrs)))
return ValidCardfileFailed(fh);
/* read all the header into memory */
#if !defined (WIN32)
for(i = 0; i < nCards; i++)
MyByteReadFile(fh, &Cards[i], sizeof(CARDHEADER));
#else
// Lack of packing on WIN32...
for (i = 0; i < nCards; i++)
{
MyByteReadFile (fh, &(Cards[i].reserved), 6);
MyByteReadFile (fh, &(Cards[i].lfData), 4);
MyByteReadFile (fh, &(Cards[i].flags), 1);
if (fType == UNICODE_FILE)
MyByteReadFile (fh, Cards[i].line, ByteCountOf(LINELENGTH+1));
else
MyAnsiReadFile (fh, CP_ACP, Cards[i].line, LINELENGTH+1);
}
#endif
/* read each card data */
for (i = 0; i < nCards; i++)
{
/* seek to card data */
if (MyFileSeek (fh, Cards[i].lfData, 0) == -1 ||
!PicRead (&Card, fh, !fOLE || (fType == OLD_FORMAT)) ||
TextRead (fh, szText, fType) < 0)
{
GlobalUnlock (hHdrs);
GlobalFree (hHdrs);
return ValidCardfileFailed(fh);
}
if (Card.lpObject)
PicDelete (&Card);
}
GlobalUnlock (hHdrs);
GlobalFree (hHdrs);
MyCloseFile (fh);
return TRUE;
}
#ifndef WIN32
#define RINT int
#else
#define RINT short
#endif