I'm trying to make 150 bytes write in UNBEFFERED MODE (for test) but i miss something... if some one can help ? the computed alignment sim to be right but still have a wrong data written data on the file... the requirement are: Size needed: 1024 Allocated pointer address at: DB6154D0 Allocated pointer address Aligned at: DB615600
#include <Windows.h>
#include <iostream>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include <string>
void DisplayError(LPTSTR lpszFunction);
// Macro Given by Microsoft for computing the closest even interval from the progam need.
#define ROUND_UP_SIZE(Value,Pow2) ((SIZE_T) ((((ULONG)(Value)) + (Pow2) - 1) & (~(((LONG)(Pow2)) - 1))))
#define ROUND_UP_PTR(Ptr,Pow2) ((void *) ((((ULONG_PTR)(Ptr)) + (Pow2) - 1) & (~(((LONG_PTR)(Pow2)) - 1))))
// Config structure for Unbeffered IO.
struct HandleConfig {
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumberOfFreeClusters;
DWORD TotalNumberOfClusters;
};
void MesureDisk(HandleConfig* config, BOOL debug) {
DWORD lpSectorsPerCluster;
DWORD lpBytesPerSector;
DWORD lpNumberOfFreeClusters;
DWORD lpTotalNumberOfClusters;
if (GetDiskFreeSpaceA(
NULL,
&lpSectorsPerCluster,
&lpBytesPerSector,
&lpNumberOfFreeClusters,
&lpTotalNumberOfClusters)) {
if (!debug) {
std::cout << "Disk measure Ok.\r\n";
}
else {
std::cout << "Disk measure Ok.\r\n";
std::cout << "Disk Structure: " << "\r\n" <<
"SectorsPerCluster: " << lpSectorsPerCluster << "\r\n" <<
"lpBytesPerSector: " << lpBytesPerSector << "\r\n" <<
"lpNumberOfFreeClusters: " << lpNumberOfFreeClusters << "\r\n" <<
"lpTotalNumberOfClusters: " << lpTotalNumberOfClusters << "\r\n";
}
}
config->SectorsPerCluster = lpSectorsPerCluster;
config->BytesPerSector = lpBytesPerSector;
config->NumberOfFreeClusters = lpNumberOfFreeClusters;
config->TotalNumberOfClusters = lpTotalNumberOfClusters;
}
void Windows_write_UNBEFFERED() {
// Config the handle.
HANDLE hFile;
char DataBuffer[] = "Some data for test !\r\n";
DWORD dwBytesToWrite = 150;//(DWORD)strlen(DataBuffer);
DWORD dwBytesWritten = 0;
LPCSTR filePath = "File.txt"; // File PATH.
hFile = CreateFileA(
filePath,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_FLAG_NO_BUFFERING, //Set Flag
NULL
);
// Measure the disc.
HandleConfig fileConf;
MesureDisk(&fileConf, TRUE);//Display the struct on Terminal.
// Ensure you have one more sector than WRITE_SIZE would require.
size_t sizeNeeded = fileConf.BytesPerSector + ROUND_UP_SIZE(dwBytesToWrite, fileConf.BytesPerSector);
char* Buffer = new char[sizeNeeded]; //heap Allocation
void* BufferAligned = ROUND_UP_PTR(Buffer, fileConf.BytesPerSector); //Offset the allocated Pointer from the disk Nomenclature.
printf("sizeneeded: %d \r\n", sizeNeeded);
printf("Allocated pointer address at: %X \r\n",Buffer );
printf("Allocated pointer address Aligned at: %X \r\n", BufferAligned);
// void* BU = VirtualAlloc(NULL, dwBytesToWrite, MEM_COMMIT,PAGE_READWRITE);
if (!WriteFile(
hFile,
BufferAligned,
sizeNeeded,
&dwBytesWritten,
NULL)) {
DWORD message = GetLastError();
DisplayError((LPTSTR)&message);
delete[] Buffer;
CloseHandle(hFile);
return;
}
CloseHandle(hFile);
// VirtualFree(BU, 0, MEM_RELEASE);
delete[] Buffer;
}
int main() {
Windows_write_UNBEFFERED();
return EXIT_SUCCESS;
}
void DisplayError(LPTSTR lpszFunction)
// Routine Description:
// Retrieve and output the system error message for the last-error code
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL);
lpDisplayBuf =
(LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)
+ lstrlen((LPCTSTR)lpszFunction)
+ 40) // account for format string
* sizeof(TCHAR));
if (FAILED(StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error code %d as follows:\n%s"),
lpszFunction,
dw,
lpMsgBuf)))
{
printf("FATAL ERROR: Unable to output error code.\n");
}
_tprintf(TEXT("ERROR: %s\n"), (LPCTSTR)lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
I'm trying to write 150 bytes in UNBEFFERED mode on windows with WriteFile() into a simple file but something is missing this code compile but produce a file with wrong content.
#include <Windows.h>
#include <iostream>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include <string>
#include <chrono>
using namespace std::chrono;
void DisplayError(LPTSTR lpszFunction);
// Macro Given by Microsoft for computing the closest even interval from the progam need.
#define ROUND_UP_SIZE(Value,Pow2) ((SIZE_T) ((((ULONG)(Value)) + (Pow2) - 1) & (~(((LONG)(Pow2)) - 1))))
#define ROUND_UP_PTR(Ptr,Pow2) ((void *) ((((ULONG_PTR)(Ptr)) + (Pow2) - 1) & (~(((LONG_PTR)(Pow2)) - 1))))
// Config structure for Unbeffered IO.
struct HandleConfig {
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumberOfFreeClusters;
DWORD TotalNumberOfClusters;
};
void MesureDisk(HandleConfig* config, BOOL debug) {
DWORD lpSectorsPerCluster;
DWORD lpBytesPerSector;
DWORD lpNumberOfFreeClusters;
DWORD lpTotalNumberOfClusters;
if (GetDiskFreeSpaceA(
NULL,
&lpSectorsPerCluster,
&lpBytesPerSector,
&lpNumberOfFreeClusters,
&lpTotalNumberOfClusters)) {
if (!debug) {
std::cout << "Disk measure Ok.\r\n";
}
else {
std::cout << "Disk measure Ok.\r\n";
std::cout << "Disk Structure: " << "\r\n" <<
"SectorsPerCluster: " << lpSectorsPerCluster << "\r\n" <<
"lpBytesPerSector: " << lpBytesPerSector << "\r\n" <<
"lpNumberOfFreeClusters: " << lpNumberOfFreeClusters << "\r\n" <<
"lpTotalNumberOfClusters: " << lpTotalNumberOfClusters << "\r\n";
}
}
config->SectorsPerCluster = lpSectorsPerCluster;
config->BytesPerSector = lpBytesPerSector;
config->NumberOfFreeClusters = lpNumberOfFreeClusters;
config->TotalNumberOfClusters = lpTotalNumberOfClusters;
}
void Windows_write_UNBEFFERED() {
//Set the Data.
std::string date = std::format("Date: {:%a %b %e %H:%M:%S %Z %Y}", zoned_time{ "Europe/Paris",floor<std::chrono::seconds>(system_clock::now()) });
char DataBuffer[1024] = { "\0" };
//Quick mem copy.
size_t ct = 0;
while (date[ct] != '\0') {
DataBuffer[ct] = date.data()[ct];
ct++;
}
// Config the handle.
HANDLE hFile;
DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
DWORD dwBytesWritten = 0;
LPCWSTR filePath = L"File.txt"; // File PATH.
//Create File
hFile = CreateFileW(
filePath,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_FLAG_NO_BUFFERING, //Set Flag
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
DWORD message = GetLastError();
DisplayError((LPTSTR)&message);
CloseHandle(hFile);
return;
}
// Measure the disc.
HandleConfig fileConf;
MesureDisk(&fileConf, TRUE);//Display the struct on Terminal.
// Ensure you have one more sector than WRITE_SIZE would require.
const size_t sizeNeeded = fileConf.BytesPerSector + ROUND_UP_SIZE(dwBytesToWrite, fileConf.BytesPerSector);
//Print Current Buffer Adress and offset Constraints for UNBEFFERED IO.
printf("size needed: %d \r\n", sizeNeeded);
// Move the current file pointer in Constreined offset (test for control ...neutral modification... or write in the midle of the block).
printf("Current pointer position A: 0x%X \r\n", SetFilePointer(hFile, 0, 0, FILE_CURRENT));
if (SetFilePointer(hFile, 0x200, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {//Move 512 bytes forward.
DWORD message = GetLastError();
DisplayError((LPTSTR)&message);
printf("ERROR on Set file pointer...\r\n");
CloseHandle(hFile);
return;
}
printf("Current pointer position B: 0x%X \r\n", SetFilePointer(hFile, 0, 0, FILE_CURRENT));
// printf("Current pointer position C (reset at the begening of file): 0x%X \r\n", SetFilePointer(hFile, 0, 0, FILE_BEGIN));
// Write the file.
if (!WriteFile(
hFile,
DataBuffer,
sizeNeeded,
&dwBytesWritten,
NULL)) {
DWORD message = GetLastError();
DisplayError((LPTSTR)&message);
CloseHandle(hFile);
return;
}
CloseHandle(hFile);
}
int main() {
Windows_write_UNBEFFERED();
return EXIT_SUCCESS;
}
void DisplayError(LPTSTR lpszFunction)
// Routine Description:
// Retrieve and output the system error message for the last-error code
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL);
lpDisplayBuf =
(LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)
+ lstrlen((LPCTSTR)lpszFunction)
+ 40) // account for format string
* sizeof(TCHAR));
if (FAILED(StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error code %d as follows:\n%s"),
lpszFunction,
dw,
lpMsgBuf)))
{
printf("FATAL ERROR: Unable to output error code.\n");
}
_tprintf(TEXT("ERROR: %s\n"), (LPCTSTR)lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}