How to read MBR data on windows system - c++

I'm using a file that has MBR code at an offset of 54 bytes.
In the main() function, I'm calling OpenMBbrFile(), then ReadMbrData().
However, I'm not able to read MBR in my Buffer Properly. Please Help Me with the Issue..................................................................................................................................................................................................................................................................................................................................................................................................................
BOOL OpenMbrFile(LPWSTR sPath)
{
cout << "OpenMBR: Create Handle" << endl;
m_hMbrFile = CreateFile(sPath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL);
if (m_hMbrFile == INVALID_HANDLE_VALUE) return FALSE;
return TRUE;
}
BOOL CloseMbrFile()
{
cout << "CloseMBR: Closing Handle" << endl;
BOOL bReturn = TRUE;
if (m_hMbrFile != INVALID_HANDLE_VALUE)
bReturn = CloseHandle(m_hMbrFile);
m_hMbrFile = NULL;
cout << "Returning from CloseMBR" << endl;
return bReturn;
}
BOOL ReadMbrData()
{
cout << "ReadMBR: Initialization" << endl;
BOOL bReturn = FALSE;
DWORD dwByteRead = 0;
LARGE_INTEGER filepointer;
filepointer.QuadPart = 54; //MBR data in File at offset 54
BYTE* pBuff = NULL;
pBuff = new BYTE[512];
if (!pBuff)
{
cout << "ReadMBR: Cleaning Stuff up" << endl;
if (pBuff) delete[] pBuff;
CloseMbrFile();
ClosePhysicalDrive();
return bReturn;
}
if (m_hMbrFile == INVALID_HANDLE_VALUE) return FALSE;
cout << "ReadMBR: Setting fp" << endl;
if(!SetFilePointerEx(m_hMbrFile, filepointer, NULL, FILE_BEGIN))
{
cout << "Failed to SetFilePointer ( " << m_hMbrFile << ", " << filepointer.QuadPart << ", 0, FILE_BEGIN)" << endl;
cout << "ReadMBR: Cleaning Stuff up" << endl;
if (pBuff) delete[] pBuff;
CloseMbrFile();
ClosePhysicalDrive();
return bReturn;
}
cout << "ReadMBR: Starting to read File" << endl;
bReturn = ReadFile(m_hMbrFile, pBuff, sizeof(*pBuff), &dwByteRead, 0);
if (bReturn)
bReturn = (sizeof(*pBuff) == dwByteRead); //Need to check this condition? shd it be 512 or size of wud do??
cout << "ReadMBR: Cleaning Stuff up" << endl;
if (pBuff) delete[] pBuff;
CloseMbrFile();
ClosePhysicalDrive();
return bReturn;
}

Related

MapViewOfFile() Returns only the Last Word in the Buffer (See the Example)

I wrote a simple inter-process communication with a memory-mapped file. The code works relatively well, but I have a problem with the buffer that I'll explain shortly. Here is the code (C++, Windows):
#define UNICODE
#define _UNICODE
#include <iostream>
#include <tchar.h>
#include <Windows.h>
int wmain(int argc, wchar_t** argv)
{
if (argc != 2)
{
std::cout << "Usage: `win32mmap w` for writing, or `win32mmap r` for reading.\n";
return -1;
}
HANDLE hMapFile;
HANDLE hEvent;
HANDLE isOpened = CreateEvent(NULL, true, false, L"IsOpened"); // To check if a `win32mmap w` runs
if (wcscmp(argv[1], L"w") == 0)
{
SetEvent(isOpened);
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, L"mmapFile");
if (hMapFile == NULL)
{
std::cout << "CreateFileMapping() Error: " << GetLastError() << "\n";
return GetLastError();
}
hEvent = CreateEvent(NULL, true, false, L"mmapEvent");
if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL)
{
std::cout << "CreateEvent() Error: " << GetLastError() << "\n";
return GetLastError();
}
char* buff = (char*)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0);
if (!buff)
{
std::cout << "MapViewOfFile() Error: " << GetLastError() << "\n";
return GetLastError();
}
while (buff[0] != L'.')
{
std::cin >> buff;
SetEvent(hEvent);
}
UnmapViewOfFile(buff);
}
else if (wcscmp(argv[1], L"r") == 0)
{
if (WaitForSingleObject(isOpened, 0) == WAIT_TIMEOUT)
{
std::cout << "Waiting for `win32mmap w`...";
WaitForSingleObject(isOpened, INFINITE);
std::cout << "\n";
}
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, L"mmapFile");
if (hMapFile == NULL)
{
std::cout << "CreateFileMapping() Error: " << GetLastError() << "\n";
return GetLastError();
}
hEvent = OpenEvent(EVENT_ALL_ACCESS, false, L"mmapEvent");
if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL)
{
std::cout << "CreateFile() Error: " << GetLastError() << "\n";
return GetLastError();
}
char* buff = (char*)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
if (!buff)
{
std::cout << "MapViewOfFile() Error: " << GetLastError() << "\n";
return GetLastError();
}
if (!buff)
{
std::cout << "MapViewOfFile() Error: " << GetLastError() << "\n";
return GetLastError();
}
while (true)
{
WaitForSingleObject(hEvent, INFINITE);
ResetEvent(hEvent);
if (buff[0] == '.')
{
break;
}
std::cout << buff << "\n";
}
UnmapViewOfFile(buff);
}
else
{
std::cout << "Usage: `win32mmap w` for writing, or `win32mmap r` for reading.\n";
return -1;
}
CloseHandle(hMapFile);
return 0;
}
The program is a simple inter-process communication "chat" that relies on memory-mapped files. To use the program, you need to make two executable instance of the program: win32mmap w and win32mmap r. The first instance is used to type text that is displayed in the second instance. When you type . in the first instance, both of them are terminated.
My problem is when I run the 2 instances of the program, and I type the world Hello in the first instance (win32mmap w), the second instance shows Hello as expected. But when I type Hello World in the first instance, the second instance shows only the word World instead of Hello World. How can I fix the code that the buffer will get the whole text?
Your writer is not waiting for the reader to consume the data before overwriting it with new data.
You need 2 events - one for the reader to wait on signaling when the buffer has data to read, and one for the writer to wait on signaling when the buffer needs data.
Try this instead:
#define UNICODE
#define _UNICODE
#include <iostream>
#include <tchar.h>
#include <Windows.h>
const DWORD BufSize = 1024;
int wmain(int argc, wchar_t** argv)
{
if (argc != 2)
{
std::cout << "Usage: `win32mmap w` for writing, or `win32mmap r` for reading.\n";
return -1;
}
HANDLE hMapFile;
char* buff;
HANDLE hNeedDataEvent;
HANDLE hHasDataEvent;
DWORD dwError;
HANDLE isOpened = CreateEvent(NULL, TRUE, FALSE, L"IsOpened"); // To check if a `win32mmap w` runs
if (isOpened == NULL)
{
dwError = GetLastError();
std::cout << "CreateEvent() Error: " << dwError << "\n";
return dwError;
}
if (wcscmp(argv[1], L"w") == 0)
{
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BufSize, L"mmapFile");
if (hMapFile == NULL)
{
dwError = GetLastError();
std::cout << "CreateFileMapping() Error: " << dwError << "\n";
SetEvent(isOpened);
return dwError;
}
buff = (char*) MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, BufSize);
if (!buff)
{
dwError = GetLastError();
std::cout << "MapViewOfFile() Error: " << dwError << "\n";
SetEvent(isOpened);
return dwError;
}
hNeedDataEvent = CreateEvent(NULL, TRUE, TRUE, L"mmapNeedDataEvent");
if (hNeedDataEvent == NULL)
{
dwError = GetLastError();
std::cout << "CreateEvent() Error: " << dwError << "\n";
SetEvent(isOpened);
return dwError;
}
hHasDataEvent = CreateEvent(NULL, TRUE, FALSE, L"mmapHasDataEvent");
if (hHasDataEvent == NULL)
{
dwError = GetLastError();
std::cout << "CreateEvent() Error: " << dwError << "\n";
SetEvent(isOpened);
return dwError;
}
SetEvent(isOpened);
while (WaitForSingleObject(hNeedDataEvent, INFINITE) == WAIT_OBJECT_0)
{
std::cin.get(buff, BufSize);
ResetEvent(hNeedDataEvent);
SetEvent(hHasDataEvent);
if (buff[0] == L'.') break;
}
}
else if (wcscmp(argv[1], L"r") == 0)
{
if (WaitForSingleObject(isOpened, 0) == WAIT_TIMEOUT)
{
std::cout << "Waiting for `win32mmap w`...";
WaitForSingleObject(isOpened, INFINITE);
std::cout << "\n";
}
hMapFile = OpenFileMapping(FILE_MAP_READ, FALSE, L"mmapFile");
if (hMapFile == NULL)
{
dwError = GetLastError();
std::cout << "CreateFileMapping() Error: " << dwError << "\n";
return dwError;
}
char* buff = (char*) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, BufSize);
if (!buff)
{
dwError = GetLastError();
std::cout << "MapViewOfFile() Error: " << dwError << "\n";
return dwError;
}
hNeedDataEvent = OpenEvent(SYNCHRONIZE, FALSE, L"mmapNeedDataEvent");
if (hNeedDataEvent == NULL)
{
dwError = GetLastError();
std::cout << "OpenEvent() Error: " << dwError << "\n";
return dwError;
}
hHasDataEvent = OpenEvent(SYNCHRONIZE, FALSE, L"mmapHasDataEvent");
if (hHasDataEvent == NULL)
{
dwError = GetLastError();
std::cout << "OpenEvent() Error: " << dwError << "\n";
return dwError;
}
do
{
SetEvent(hNeedDataEvent);
if (WaitForSingleObject(hHasDataEvent, INFINITE) != WAIT_OBJECT_0)
break;
std::cout << buff << "\n";
ResetEvent(hHasDataEvent);
}
while (buff[0] != '.');
}
else
{
std::cout << "Usage: `win32mmap w` for writing, or `win32mmap r` for reading.\n";
return -1;
}
UnmapViewOfFile(buff);
CloseHandle(hMapFile);
CloseHandle(hNeedDataEvent);
CloseHandle(hHasDataEvent);
CloseHandle(isOpened);
return 0;
}

WriteProcessMemory not working for some reason

This is all the source code for a program i'm trying to make, and I can't get WriteProcessMemory to work at all. It returns the correct messages, saying that everything went successfully, but nothing actually changes in the game. Does anyone know of a fix?
#include <iostream>
#include <Windows.h>
using namespace std;
// variables
int plcHold = 1;
string hlthLoop = "OFF";
string ammoLoop = "OFF";
DWORD pid;
DWORD playerAddr;
DWORD hlthOffs = 0xF8;
// main function
int main()
{
// finding pid, opening proc, finding player address
HWND hwnd = FindWindowA(NULL, "AssaultCube");
if(hwnd == NULL)
{
cout << "Error; Couldn't find window" << endl;
} else{
GetWindowThreadProcessId(hwnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(pHandle == NULL)
{
cout << "Error; Couldn't open process" << endl;
} else{
ReadProcessMemory(pHandle, (LPCVOID)0x50F4F4, &playerAddr, sizeof(playerAddr), 0);
if(ReadProcessMemory != FALSE)
{
cout << "Health successfully read!" << endl;
} else{
cout << "Error code " << GetLastError << endl;
}
}
while(plcHold == 1){
cout << "========== *****'s Assault Cube Trainer ==========\n" << endl;
cout << "=============== Health Loop - " << hlthLoop << " ================" << endl;
Sleep(1500);
system("cls");
if(GetAsyncKeyState(0x5A))
{
cout << "Health successfully edited!" << endl;
WriteProcessMemory(pHandle, LPVOID(playerAddr + hlthOffs), 0, sizeof(999), 0);
CloseHandle(pHandle);
}
}
}
return 0;
}
You're passing a null pointer to WriteProcessMemory for the third (lpBuffer) parameter. You have to pass the address of the actual value, not the value itself. If you want to write an integer value, try this:
DWORD val = 0; // or 999?
WriteProcessMemory(
pHandle, static_cast<LPVOID>(playerAddr + hlthOffs),
&val, sizeof(val), 0);

EXPLICIT_ACCESS array from ACL - WIN32 API

void main() {
PSID UserSID = NULL;
PSID GroupSID = NULL;
PSECURITY_DESCRIPTOR SD = NULL;
ACL *pDACL = new ACL ;
string input, ext = "";
wcout << "Enter the location : " << endl;
std::getline(cin, input);
LPCSTR file = input.c_str();
HANDLE hFile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_ACCESS_DENIED)
{
cout << "Access Denied : System Files" << endl;
return;
}
else if (GetLastError() == ERROR_PATH_NOT_FOUND)
{
cout << "Path Name Not Found" << endl;
return;
}
else if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
cout << "File Not Found" << endl;
return;
}
else
{
cout << GetLastError() << endl;
return;
}
}
ULONG Count = NULL;
PEXPLICIT_ACCESS_W *pExplicitEntries = new PEXPLICIT_ACCESS_W;
if (GetSecurityInfo(hFile,SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &SD) == ERROR_SUCCESS)
{
cout << "GetSecInfo Success " << pDACL->AceCount << endl;
cout << GetLastError() << endl;
}
if (GetExplicitEntriesFromAclW(pDACL, &Count, pExplicitEntries) == ERROR_SUCCESS)
{
cout << Count << endl;
cout << GetLastError() << endl;
}
if (pExplicitEntries[0]->Trustee.TrusteeForm == TRUSTEE_IS_SID)
{
TCHAR AccountBuff[80];
TCHAR DomainBuff[80];
DWORD AccountBufflength = 40;
DWORD DomainBufflength = 40;
PSID_NAME_USE peUse = new SID_NAME_USE;
PSID Sid = pExplicitEntries[0]->Trustee.ptstrName;
LookupAccountSidW(NULL, Sid, AccountBuff, &AccountBufflength, DomainBuff, &DomainBufflength, peUse);
wcout << AccountBuff << endl;
DWORD pAccessRights;
if (GetEffectiveRightsFromAclW(pDACL, &pExplicitEntries[0]->Trustee, &pAccessRights) == ERROR_SUCCESS)
{
DisplayAccessMask(pAccessRights);
}
}
}
Currently, the array index is 0, if i switch to other index like 1 or 2, it causes exception : Accessing location. Please Help, please someone give me solution to access all the trustee in the ACL and get the access permission and username of each trustee of a file
GetSecurityInfo gives me ACE count as 4 , but when it comes to the
GetExplicitEntriesFromAclW the Count value remains 0.
I can reproduce this issue when my test target file is an new created, for example, TXT file. Yes, GetSecurityInfo gives me ACE count as 4 , but when it comes to the GetExplicitEntriesFromAclW the Count value remains 0.
Use function to check the ACE type and found that all types are 0: ACCESS_MIN_MS_ACE_TYPE \ ACCESS_ALLOWED_ACE_TYPE.
if (GetSecurityInfo(hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &SD) == ERROR_SUCCESS)
{
cout << "GetSecInfo Success " << pDACL->AceCount << endl;
cout << GetLastError() << endl;
}
PACL pAcl = pDACL;
int aceNum = pDACL->AceCount;
for (int i = 0; i < aceNum; i++)
{
ACE_HEADER *aceAddr = NULL;
if (GetAce(pAcl, i, (void**)(&aceAddr)))
{
printf("ACE type: %d \n",aceAddr->AceType); ACCESS_ALLOWED_ACE_TYPE;
printf("ACE flags: %d \n", aceAddr->AceFlags);
printf("ACE size: %d \n", aceAddr->AceSize);
}
}
If you set deny write operation for current user like this:
Then ACE type 1 (ACCESS_DENIED_ACE_TYPE) appears. And the Count value returned from the GetExplicitEntriesFromAclW equals the number of entries whose ACE type is 1. See the following snapshot:
Looks like you are passing null EXPLICIT_ACCESS_W to GetExplicitEntriesFromAclW.
So try either:
EXPLICIT_ACCESS_W *pExplicitEntries=NULL;
EXPLICIT_ACCESS_W **pExplicitEntries2=&pExplicitEntries;
GetExplicitEntriesFromAclA(pacl,&countExplicitACL,pExplicitEntries2);
or:
EXPLICIT_ACCESS_W *pExplicitEntries =NULL;
GetExplicitEntriesFromAclA(pacl,&countExplicitACL,&pExplicitEntries2);
Both serve your purpose. Beware of NULL pointers.

CreateDC returns an error 1801

I need to receive screenshots from MS Mirror driver, but unexpectedly I noticed, that CreateDC() function returns NULL and GetLastError gives me Error#1801 ("The printer name is invalid")
extern "C" __declspec(dllexport) HDC InitDC() {
DWORD dwAttach = 0;
DEVMODE devmode;
// Make sure we have a display on this thread.
BOOL change = EnumDisplaySettings(NULL,
ENUM_CURRENT_SETTINGS,
&devmode);
LPCWSTR driverName = L"Microsoft Mirror Driver";
devmode.dmFields = DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT |
DM_POSITION ;
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
if (change)
{
// query all display devices in the system until we hit a primary
// display device. Using it get the width and height of the primary
// so we can use that for the mirror driver. Also enumerate the
// display devices installed on this machine untill we hit
// our favourate mirrored driver, then extract the device name string
// of the format '\\.\DISPLAY#'
DISPLAY_DEVICE dispDevice;
FillMemory(&dispDevice, sizeof(DISPLAY_DEVICE), 0);
dispDevice.cb = sizeof(DISPLAY_DEVICE);
LPCWSTR deviceName = NULL;
devmode.dmDeviceName[0] = '\0';
INT devNum = 0;
BOOL result;
DWORD cxPrimary = 0xFFFFFFFF;
DWORD cyPrimary = 0xFFFFFFFF;
// First enumerate for Primary display device:
while ((result = EnumDisplayDevices(NULL,
devNum,
&dispDevice,
0)) == TRUE)
{
wcout << "DriverName: " << dispDevice.DeviceString << endl;
wcout << "DevName: " << dispDevice.DeviceName << endl;
if (dispDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
{
// Primary device. Find out its dmPelsWidht and dmPelsHeight.
EnumDisplaySettings(dispDevice.DeviceName,
ENUM_CURRENT_SETTINGS,
&devmode);
cxPrimary = devmode.dmPelsWidth;
cyPrimary = devmode.dmPelsHeight;
wcout << "Selected Primary DevName (width, height): " << dispDevice.DeviceName << " (" << cxPrimary << "," << cyPrimary << ")" << endl << endl;
break;
}
devNum++;
}
// error check
if (!result)
{
wcout << "No " << driverName << " found " << endl;
exit(0);
}
if (cxPrimary == 0xffffffff || cyPrimary == 0xffffffff)
{
wcout << "cxPrimary or cyPrimary not valid" << endl;
exit(0);
}
// Enumerate again for the mirror driver:
devNum = 0;
while ((result = EnumDisplayDevices(NULL,
devNum,
&dispDevice,
0)) == TRUE)
{
LPCWSTR devString = dispDevice.DeviceString;
wcout << " devString: "<< devString << endl;
if (wcscmp(devString, driverName ) == 0) {
wcout << " Driver selected: "<< driverName << endl;
break;
}
devNum++;
}
// error check
if (!result)
{
wcout << "No " << driverName << " found " << endl;
exit(0);
}
wcout << "DevNum " << devNum << endl <<
"DeviceName: " << dispDevice.DeviceName << endl <<
"DeviceString: " << dispDevice.DeviceString << endl <<
"DeviceID: " << dispDevice.DeviceID << endl <<
"DeviceKey: " << dispDevice.DeviceKey << endl;
CHAR *deviceNum = new CHAR[MAX_PATH];
LPSTR deviceSub;
// Simply extract 'DEVICE#' from registry key. This will depend
// on how many mirrored devices your driver has and which ones
// you intend to use.
_wcsupr(&dispDevice.DeviceKey[0]);
deviceSub = (LPSTR)(wcsstr(&dispDevice.DeviceKey[0],
L"\\DEVICE"));
if (!deviceSub) {
printf("deviceSub - yes \n");
deviceNum[0] = (CHAR)(((string)("DEVICE0")).c_str());
}
else {
printf("!deviceSub \n");
deviceNum[0] = (CHAR)(((string)("DEVICE1")).c_str());
}
// Reset the devmode for mirror driver use:
FillMemory(&devmode, sizeof(DEVMODE), 0);
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
devmode.dmFields = DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT |
DM_POSITION;
//wcscpy( devmode.dmDeviceName, sizeof(devmode.dmDeviceName, L"mirror" );
deviceName = dispDevice.DeviceName;
StringCbCopy(devmode.dmDeviceName, sizeof(devmode.dmDeviceName), dispDevice.DeviceName);
wcout << "dmDeviceName: " << devmode.dmDeviceName << endl;
wcout << "deviceName: " << deviceName << endl;
wcout << "driverName: " << driverName << endl;
/* !!! THE PROBLEM IS HERE !!!*/
HDC hdc = CreateDC(driverName, deviceName, NULL, &devmode );
if ( hdc == NULL ) {
wcout << "CreateDC error: " << GetLastError() << endl;
return NULL;
}
return hdc;
}
return NULL;
}
Thanks for an assistance!
UPD1:
deviceName = "\\.\DISPLAYV1"
driverName = "Microsoft Mirror Driver"
devmode.dmDeviceName = "\\.\DISPLAYV1"

Problems with backbuffer and EndScene hook

So, i've been trying to retrieve the backbuffer data using a EndScene hook, the thing is that for some reason my GetBackBuffer is returning a invalid result (i think) because when i use pSurface->GetDesc() it returns that the backbuffer has Width 1 and height 1, and it always return the pBits filled with 0.
HRESULT WINAPI hkEndScene(LPDIRECT3DDEVICE9 pDevice)
{
IDirect3DSurface9* pSurface = 0;
IDirect3DSurface9* pBBuffer = 0;
D3DLOCKED_RECT Lock;
D3DSURFACE_DESC desc;
if (pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface) != D3D_OK)
{
logg << "ERROR GetBackBuffer: " << GetLastError() << endl;
return pEndScene(pDevice);
}
pSurface->GetDesc(&desc);
logg << "Size: " << desc.Width << ", " << desc.Height << endl;
HRESULT hRes = pDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pBBuffer, NULL);
if (hRes != D3D_OK)
{
logg << "ERROR CreateOffscreenPlainSurface: " << GetLastError() << endl;
return pEndScene(pDevice);
}
hRes = pDevice->GetRenderTargetData(pSurface, pBBuffer);
if (hRes != D3D_OK)
{
logg << "ERROR GetRenderTargetData: " << GetLastError() << endl;
return pEndScene(pDevice);
}
pBBuffer->LockRect(&Lock, NULL, D3DLOCK_READONLY);
Com.DrawBuffer(Lock.pBits);
logg << Lock.pBits << endl;
//Usual free memory functions
pSurface->Release();
pBBuffer->UnlockRect();
pBBuffer->Release();
return pEndScene(pDevice);
}