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.
 
 
 
 
 
 

176 lines
4.7 KiB

#include "stdinc.h"
#include "win32file.h"
#include "atlbase.h"
#include "atlconv.h"
#define IS_NT() ((GetVersion() & 0x80000000) == 0)
using std::wstring;
void Win32File::snarfFullFile(wstring& output)
{
output = L"";
CByteVector bytes;
DWORD dwReadSize = 0;
bytes.resize(filesize() - filepointer());
if (!ReadFile(_hFile, &bytes.front(), bytes.size(), &dwReadSize, NULL))
{
throw new ReadWriteError(false, ::GetLastError());
}
// Otherwise, bash the byte vector into a wstring for output
output = ConvertToWstring(bytes, _type);
}
void Win32File::writeLine(const wstring& dump)
{
CByteVector vb;
DWORD dwWritten;
vb = ConvertWstringToDestination(dump, _type);
if (!WriteFile(_hFile, &vb.front(), vb.size(), &dwWritten, NULL))
throw new ReadWriteError(true, ::GetLastError());
}
bool Win32File::eof() { return false; }
void
Win32File::openForRead(wstring wstname)
{
USES_CONVERSION;
if (_hFile != INVALID_HANDLE_VALUE)
{
throw new AlreadyOpened;
}
const PCWSTR pcwstr = wstname.c_str();
const DWORD Flags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN;
_hFile =
IS_NT() ? CreateFileW(pcwstr, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, Flags, NULL)
: CreateFileA(W2A(pcwstr), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, Flags, NULL);
if (_hFile == INVALID_HANDLE_VALUE || _hFile == NULL)
{
throw new OpeningError(GetLastError());
}
// If this was for reading, then sniff the first few bytes and see what kind
// of file it is.
DWORD dwReadBytes = 0;
BYTE bBuffer[256];
if (!ReadFile(_hFile, bBuffer, sizeof(bBuffer), &dwReadBytes, NULL))
{
throw new ReadWriteError(true, GetLastError());
}
// Now let's determine what kind of buffer we've got
_type = DetermineFileTypeFromBuffer(bBuffer, dwReadBytes);
_bOpenForRead = true;
// Let's zip the file pointer past the first gunk
SetFilePointer(_hFile, DetermineFileTypeSigSize(_type), NULL, FILE_BEGIN);
}
void
Win32File::openForWrite(wstring wstname, FileContentType fct, bool bOverwrite)
{
USES_CONVERSION;
if (_hFile != INVALID_HANDLE_VALUE)
{
throw new AlreadyOpened;
}
const DWORD OpenOrCreate = bOverwrite ? CREATE_ALWAYS : CREATE_NEW;
const DWORD Flags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN;
PCWSTR pcwstr = wstname.c_str();
_hFile =
IS_NT() ? CreateFileW(pcwstr, GENERIC_WRITE, FILE_SHARE_READ, NULL, OpenOrCreate, Flags, NULL)
: CreateFileA(W2A(pcwstr), GENERIC_WRITE, FILE_SHARE_READ, NULL, OpenOrCreate, Flags, NULL);
if (_hFile == INVALID_HANDLE_VALUE || _hFile == NULL)
{
throw new OpeningError(GetLastError());
}
// Now that we have an open file, let's blop the signature bytes into it.
DWORD dwWritten;
DWORD dwToWrite;
PCVOID pvWriteBuffer;
switch (fct) {
case FileContentsUnicode:
pvWriteBuffer = UNICODE_SIGNATURE;
dwToWrite = sizeof(UNICODE_SIGNATURE);
break;
case FileContentsUnicodeBigEndian:
pvWriteBuffer = UNICODE_BIG_ENDIAN_SIGNATURE;
dwToWrite = sizeof(UNICODE_BIG_ENDIAN_SIGNATURE);
break;
case FileContentsUTF8:
pvWriteBuffer = NULL;
dwToWrite = 0;
break;
default:
pvWriteBuffer = UNICODE_SIGNATURE;
dwToWrite = 0;
break;
}
if (!WriteFile(_hFile, pvWriteBuffer, dwToWrite, &dwWritten, NULL) || (dwWritten != dwToWrite)) {
throw new ReadWriteError(false, GetLastError());
}
_bOpenForRead = false;
_type = fct;
}
Win32File::Win32File()
: _hFile(INVALID_HANDLE_VALUE), _type(FileContentsUTF8),
_bOpenForRead(false), _bEof(false)
{
}
Win32File::~Win32File() { if (_hFile != INVALID_HANDLE_VALUE) { CloseHandle(_hFile); } };
FileContentType DetermineFileTypeFromBuffer(unsigned char *data, int length)
{
#define CHECKMARK(tp, ct) if ((length > sizeof(tp)) && (memcmp(data, tp, sizeof(tp)) == 0)) return ct;
CHECKMARK(UNICODE_SIGNATURE, FileContentsUnicode);
CHECKMARK(UNICODE_BIG_ENDIAN_SIGNATURE, FileContentsUnicodeBigEndian);
CHECKMARK(UTF8_SIGNATURE, FileContentsUTF8);
return FileContentsUTF8;
}
int DetermineFileTypeSigSize(FileContentType type)
{
switch (type)
{
case FileContentsUnicode: return sizeof(UNICODE_SIGNATURE);
case FileContentsUnicodeBigEndian: return sizeof(UNICODE_BIG_ENDIAN_SIGNATURE);
case FileContentsUTF8:
default: return 0;
}
}