I have problem with this program.
This program is supposed to copy corrupted files from a DVD or CD to any other drive. I used ReadFile() function from Win32 API. This function is supposed to return ERROR_READ_FAULT value when there occures a read error from the disk (At least according to the MSDN!). But, on the contrary, the program stucks when any read error occures.
So, I am looking for an alternative function or something else. Any function that returns an error code, not stucks.
Code:
#include <windows.h>
#include <commctrl.h>
#include <stdlib.h>
HWND hWnd;
HWND hsSource, hsTarget, hsDone, hslStatus, hsStatus, hsPriority;
HWND heSource, heTarget;
HWND hbProceed, hbPause, hbCancel;
HWND hbShutdown;
HWND hpProgress, hcbComboBox;
HANDLE hsFile, htFile;
const DWORD BUFFER_SIZE = 32768;
char lpszBuffer[BUFFER_SIZE];
DWORD dwFileSize, dwFileBlockPosition = 0, dwFileBytePosition = 0;
char lpszSourceFileName[256], lpszTargetFileName[256];
LONG nWidth=400, nHeight=180;
BOOL bResult;
LONG npbPosition;
UINT CBP_IDLE;
UINT CBP_LOW;
UINT CBP_NORMAL;
UINT CBP_HIGH;
UINT CBP_CRITICAL;
UINT uPriority;
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
UINT CopyFile (HANDLE hSource, HANDLE hTarget, LPSTR lpszData, DWORD dwNumberOfBytes);
char ERROR_DATA[] = "X";
const UINT CS_IDLE = 0;
const UINT CS_PROCEED = 1;
const UINT CS_CORRUPT = 2;
const UINT CS_PAUSE = 3;
UINT uCurrentState = CS_IDLE;
const UINT CF_SUCCESS = 0;
const UINT CF_EOF = 1;
const UINT CF_ERROR = 2;
UINT uCopyFile;
const UINT TMR_ID = 1;
const UINT TMR_ELAPSE = 100; //miliseconds
UINT PB_LOWLIMIT = 0;
UINT PB_HILIMIT;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
{
MSG Msg;
LONG nControlHeights = 16;
char szClassName[] = "WindowsApp";
WNDCLASSEX WindowClass;
WindowClass.cbSize = sizeof (WNDCLASSEX);
WindowClass.style = CS_DBLCLKS;
WindowClass.lpfnWndProc = WindowProcedure;
WindowClass.cbClsExtra = 0;
WindowClass.cbWndExtra = 0;
WindowClass.hInstance = hInstance;
WindowClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
WindowClass.hCursor = LoadCursor (NULL, IDC_ARROW);
WindowClass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
WindowClass.lpszMenuName = NULL;
WindowClass.lpszClassName = szClassName;
WindowClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
if (!RegisterClassEx (&WindowClass)) return 0;
hWnd = CreateWindowEx ( (DWORD) 0,
(LPCSTR) szClassName,
(LPCSTR) "~ Salvation Of The Souls ~",
(DWORD) WS_MINIMIZEBOX | WS_SYSMENU,
(LONG) CW_USEDEFAULT,
(LONG) CW_USEDEFAULT,
(LONG) nWidth,
(LONG) nHeight,
(HWND) HWND_DESKTOP,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
ShowWindow(hWnd, nFunsterStil);
LONG nssLeft = 5, nssTop = 5;
LONG nssWidth = 55, nssHeight = nControlHeights;
hsSource = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "STATIC",
(LPCSTR) "Source :",
(DWORD) WS_VISIBLE | WS_CHILD,
(LONG) nssLeft,
(LONG) nssTop,
(LONG) nssWidth,
(LONG) nssHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG nstLeft = nssLeft, nstTop = nssTop + nssHeight + 5;
LONG nstWidth = 55, nstHeight = nControlHeights;
hsTarget = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "STATIC",
(LPCSTR) "Target :",
(DWORD) WS_VISIBLE | WS_CHILD,
(LONG) nstLeft,
(LONG) nstTop,
(LONG) nstWidth,
(LONG) nstHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG nesLeft = nssLeft + nssWidth + 5, nesTop = nssTop;
LONG nesWidth = 320, nesHeight = nControlHeights;
heSource = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "EDIT",
(LPCSTR) NULL,
(DWORD) WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL,
(LONG) nesLeft,
(LONG) nesTop,
(LONG) nesWidth,
(LONG) nesHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG netLeft = nesLeft, netTop = nstTop;
LONG netWidth = nesWidth, netHeight = nControlHeights;
heTarget = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "EDIT",
(LPCSTR) NULL,
(DWORD) WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL,
(LONG) netLeft,
(LONG) netTop,
(LONG) netWidth,
(LONG) netHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG nsdLeft = nssLeft, nsdTop = nstTop + nstHeight + 5;
LONG nsdWidth = nssWidth, nsdHeight = nControlHeights;
hsDone = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "STATIC",
(LPCSTR) "0 %",
(DWORD) WS_VISIBLE | WS_CHILD | SS_CENTER,
(LONG) nsdLeft,
(LONG) nsdTop,
(LONG) nsdWidth,
(LONG) nsdHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
InitCommonControls();
LONG npLeft = nsdLeft + nsdWidth + 5, npTop = nsdTop;
LONG npWidth = 320, npHeight = nControlHeights;
hpProgress = CreateWindowEx((DWORD) NULL,
(LPCSTR) PROGRESS_CLASS,
(LPCSTR) NULL,
(DWORD) WS_VISIBLE | WS_CHILD | PBS_SMOOTH,
(LONG) npLeft,
(LONG) npTop,
(LONG) npWidth,
(LONG) npHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG nbpLeft = nssLeft, nbpTop = npTop + npHeight + 5;
LONG nbpWidth = 100, nbpHeight = 2 * nControlHeights;
hbProceed = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "BUTTON",
(LPCSTR) "Proceed",
(DWORD) WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
(LONG) nbpLeft,
(LONG) nbpTop,
(LONG) nbpWidth,
(LONG) nbpHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG nbsLeft = nbpLeft + nbpWidth + 40, nbsTop = nbpTop;
LONG nbsWidth = nbpWidth, nbsHeight = nbpHeight;
hbPause = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "BUTTON",
(LPCSTR) "Pause",
(DWORD) WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
(LONG) nbsLeft,
(LONG) nbsTop,
(LONG) nbsWidth,
(LONG) nbsHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
EnableWindow(hbPause, FALSE);
LONG nbcLeft = nbsLeft + nbsWidth + 40, nbcTop = nbpTop;
LONG nbcWidth = nbpWidth, nbcHeight = nbpHeight;
hbCancel = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "BUTTON",
(LPCSTR) "Cancel",
(DWORD) WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
(LONG) nbcLeft,
(LONG) nbcTop,
(LONG) nbcWidth,
(LONG) nbcHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
EnableWindow(hbCancel, FALSE);
LONG nslsLeft = nssLeft, nslsTop = nbcTop + nbcHeight + 5;
LONG nslsWidth = nssWidth, nslsHeight = nControlHeights;
hslStatus = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "STATIC",
(LPCSTR) "Status :",
(DWORD) WS_VISIBLE | WS_CHILD,
(LONG) nslsLeft,
(LONG) nslsTop,
(LONG) nslsWidth,
(LONG) nslsHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG nsstLeft = nslsLeft + nslsWidth + 5, nsstTop = nslsTop;
LONG nsstWidth = nesWidth, nsstHeight = nControlHeights;
hsStatus = CreateWindowEx( (DWORD) NULL,
(LPCSTR) "STATIC",
(LPCSTR) "Press 'Proceed' to begin.",
(DWORD) WS_VISIBLE | WS_CHILD,
(LONG) nsstLeft,
(LONG) nsstTop,
(LONG) nsstWidth,
(LONG) nsstHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG nspWidth = 100, nspHeight = nControlHeights;
LONG nspLeft = nWidth - nspWidth - 20, nspTop = nsstTop;
hsPriority = CreateWindowEx((DWORD) NULL,
(LPCSTR) "STATIC",
(LPCSTR) "Priority :",
(DWORD) WS_VISIBLE | WS_CHILD,
(LONG) nspLeft,
(LONG) nspTop,
(LONG) nspWidth,
(LONG) nspHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
LONG ncbWidth = nspWidth, ncbHeight = 7 * nControlHeights;
LONG ncbLeft = nspLeft, ncbTop = nspTop + nspHeight + 5;
hcbComboBox = CreateWindowEx((DWORD) NULL,
(LPCSTR) "COMBOBOX",
(LPCSTR) "qwerty",
(DWORD) WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
(LONG) ncbLeft,
(LONG) ncbTop,
(LONG) ncbWidth,
(LONG) ncbHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
CBP_CRITICAL= SendMessage(hcbComboBox, CB_ADDSTRING, (WPARAM) NULL, (LPARAM) (LPCTSTR) "Critical");
CBP_HIGH = SendMessage(hcbComboBox, CB_ADDSTRING, (WPARAM) NULL, (LPARAM) (LPCTSTR) "High");
CBP_NORMAL = SendMessage(hcbComboBox, CB_ADDSTRING, (WPARAM) NULL, (LPARAM) (LPCTSTR) "Normal");
CBP_LOW = SendMessage(hcbComboBox, CB_ADDSTRING, (WPARAM) NULL, (LPARAM) (LPCTSTR) "Low");
CBP_IDLE = SendMessage(hcbComboBox, CB_ADDSTRING, (WPARAM) NULL, (LPARAM) (LPCTSTR) "Idle");
SendMessage(hcbComboBox, CB_SETCURSEL, (WPARAM) CBP_NORMAL, (LPARAM) NULL);
uPriority = 10;
LONG nbsdLeft = nssLeft, nbsdTop = nslsTop + nslsHeight + 10;
LONG nbsdWidth = 220, nbsdHeight = nControlHeights;
hbShutdown = CreateWindowEx((DWORD) NULL,
(LPCSTR) "BUTTON",
(LPCSTR) "Shutdown PC when completed.",
(DWORD) WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX,
(LONG) nbsdLeft,
(LONG) nbsdTop,
(LONG) nbsdWidth,
(LONG) nbsdHeight,
(HWND) hWnd,
(HMENU) NULL,
(HINSTANCE) hInstance,
(LPVOID) NULL);
HANDLE hToken;
OpenProcessToken( (HANDLE) GetCurrentProcess(),
(DWORD) TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
(PHANDLE) &hToken);
TOKEN_PRIVILEGES tpTokenPrivileges;
LookupPrivilegeValue( (LPCTSTR) NULL,
(LPCTSTR) SE_SHUTDOWN_NAME,
(PLUID) &tpTokenPrivileges.Privileges[0].Luid);
tpTokenPrivileges.PrivilegeCount = 1;
tpTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges( (HANDLE) hToken,
(BOOL) FALSE,
(PTOKEN_PRIVILEGES) &tpTokenPrivileges,
(DWORD) 0,
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);
BOOL bLoop = TRUE;
while (bLoop)
{
if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
if(Msg.message == WM_QUIT) bLoop = FALSE;
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
else
{
switch(uCurrentState)
{
case CS_PROCEED:
uCopyFile = CopyFile(hsFile, htFile, lpszBuffer, BUFFER_SIZE);
switch (uCopyFile)
{
case CF_SUCCESS:
if (uPriority) Sleep((DWORD) uPriority);
break;
case CF_EOF:
KillTimer(hWnd, TMR_ID);
EnableWindow(hbProceed, TRUE);
EnableWindow(hbPause, FALSE);
EnableWindow(hbCancel, FALSE);
CloseHandle(hsFile);
CloseHandle(htFile);
SendMessage(hpProgress, PBM_SETPOS, (WPARAM) PB_HILIMIT, (LPARAM) 0);
SendMessage(hsDone, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "% 100");
SendMessage(hsStatus, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "Completed");
uCurrentState = CS_IDLE;
if (SendMessage(hbShutdown, BM_GETCHECK, (WPARAM) NULL, (LPARAM) NULL) == BST_CHECKED)
InitiateSystemShutdown( (LPTSTR) NULL,
(LPTSTR) "Shutdown is going to proceed!",
(DWORD) 30,
(BOOL) FALSE, //Force ?
(BOOL) FALSE); //Reboot ?
break;
case CF_ERROR:
uCurrentState = CS_CORRUPT;
if (uPriority) Sleep((DWORD) uPriority);
break;
}
break;
case CS_CORRUPT:
uCopyFile = CopyFile(hsFile, htFile, lpszBuffer, BUFFER_SIZE /*disgarded*/ );
switch (uCopyFile)
{
case CF_SUCCESS:
if (uPriority) Sleep((DWORD) uPriority);
break;
case CF_EOF:
KillTimer(hWnd, TMR_ID);
EnableWindow(hbProceed, TRUE);
EnableWindow(hbPause, FALSE);
EnableWindow(hbCancel, FALSE);
CloseHandle(hsFile);
CloseHandle(htFile);
SendMessage(hpProgress, PBM_SETPOS, (WPARAM) PB_HILIMIT, (LPARAM) 0);
SendMessage(hsDone, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "% 100");
SendMessage(hsStatus, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "Completed");
uCurrentState = CS_IDLE;
if (SendMessage(hbShutdown, BM_GETCHECK, (WPARAM) NULL, (LPARAM) NULL) == BST_CHECKED)
InitiateSystemShutdown( (LPTSTR) NULL,
(LPTSTR) "Shutdown is going to proceed!",
(DWORD) 30,
(BOOL) FALSE, //Force ?
(BOOL) FALSE); //Reboot ?
break;
}
break;
case CS_PAUSE:
KillTimer(hWnd, TMR_ID);
Sleep(100);
break;
case CS_IDLE:
Sleep(100);
break;
}
}
}
return Msg.wParam;
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult;
switch (message)
{
case WM_TIMER:
if (dwFileSize)
{
SendMessage(hpProgress, PBM_SETPOS, (WPARAM) dwFileBytePosition, (LPARAM) 0);
char lpszPercentage[] = "% XXX";
_itoa(((int) 100 * dwFileBytePosition / dwFileSize), &lpszPercentage[2], 10);
SendMessage(hsDone, WM_SETTEXT, (WPARAM) NULL, (LPARAM) lpszPercentage);
}
break;
case WM_COMMAND:
switch (HIWORD(wParam))
{
case BN_CLICKED:
if ((HANDLE) lParam == (HANDLE) hbProceed)
{
if (uCurrentState == CS_IDLE)
{
lResult = SendMessage(heSource, WM_GETTEXT, 256, (LPARAM) lpszSourceFileName);
//strcpy(lpszSourceFileName, "E:\\the vilage\\The Village Dvdrip Xvid-Brutus.avi");
hsFile = CreateFile((LPCTSTR) lpszSourceFileName,
(DWORD) GENERIC_READ,
(DWORD) FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES) NULL,
(DWORD) OPEN_EXISTING,
(DWORD) FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (GetLastError())
{
MessageBox(hWnd, "Error opening source file.", "Error", MB_ICONERROR | MB_OK);
uCurrentState = CS_IDLE;
break;
}
PB_HILIMIT = dwFileSize = GetFileSize(hsFile, NULL);
SendMessage(hpProgress, PBM_SETRANGE, (WPARAM) NULL, (LPARAM) MAKELPARAM(PB_LOWLIMIT, PB_HILIMIT));
lResult = SendMessage(heTarget, WM_GETTEXT, 256, (LPARAM) lpszTargetFileName);
//strcpy(lpszTargetFileName, "C:\\Documents and Settings\\Ahmed Han\\Desktop\\The Village Dvdrip Xvid-Brutus.avi");
htFile = CreateFile((LPCTSTR) lpszTargetFileName,
(DWORD) GENERIC_WRITE,
(DWORD) FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES) NULL,
(DWORD) CREATE_ALWAYS,
(DWORD) FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (GetLastError())
{
MessageBox(hWnd, "Error opening target file.", "Error", MB_ICONERROR | MB_OK);
CloseHandle(hsFile);
uCurrentState = CS_IDLE;
break;
}
dwFileBytePosition = 0;
}
SetTimer(hWnd, TMR_ID, TMR_ELAPSE, NULL);
uCurrentState = CS_PROCEED;
SendMessage(hsStatus, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "Copying the file...");
EnableWindow(hbProceed, FALSE);
EnableWindow(hbPause, TRUE);
EnableWindow(hbCancel, TRUE);
}
else if ((HANDLE) lParam == (HANDLE) hbPause)
{
KillTimer(hWnd, TMR_ID);
EnableWindow(hbProceed, TRUE);
EnableWindow(hbPause, FALSE);
uCurrentState = CS_PAUSE;
SendMessage(hsStatus, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "Press 'Proceed' to continue");
}
else if ((HANDLE) lParam == (HANDLE) hbCancel)
{
KillTimer(hWnd, TMR_ID);
CloseHandle(hsFile);
CloseHandle(htFile);
EnableWindow(hbProceed, TRUE);
EnableWindow(hbPause, FALSE);
EnableWindow(hbCancel, FALSE);
uCurrentState = CS_IDLE;
SendMessage(hsStatus, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "Action canceled by user");
}
break;
}
break;
case CBN_SELCHANGE:
UINT uPriorityClass;
uPriorityClass = SendMessage(hcbComboBox, CB_GETCURSEL, (WPARAM) NULL, (LPARAM) NULL);
if (uPriorityClass == CBP_IDLE) uPriority = 250;
else if (uPriorityClass == CBP_LOW) uPriority = 100;
else if (uPriorityClass == CBP_NORMAL) uPriority = 25;
else if (uPriorityClass == CBP_HIGH) uPriority = 5;
else if (uPriorityClass == CBP_CRITICAL) uPriority = 0;
break;
case WM_DESTROY:
if (uCurrentState != CS_IDLE)
{
CloseHandle(hsFile);
CloseHandle(htFile);
}
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
UINT CopyFile (HANDLE hSource, HANDLE hTarget, LPSTR lpszData, DWORD dwNumberOfBytes)
{
DWORD dwNumberOfBytesRead;
DWORD dwNumberOfBytesWritten;
if (uCurrentState == CS_PROCEED)
{
bResult = ReadFile( (HANDLE) hSource,
(LPVOID) lpszData,
(DWORD) dwNumberOfBytes,
(LPDWORD) &dwNumberOfBytesRead,
(LPOVERLAPPED) NULL);
if (bResult == ERROR_READ_FAULT)
{
SetFilePointer( (HANDLE) hsFile,
(LONG) dwFileBytePosition,
(PLONG) NULL,
(DWORD) FILE_BEGIN);
uCurrentState = CS_CORRUPT;
SendMessage(hsStatus, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "Proceeding with corrupted area...");
return CF_ERROR;
}
bResult = WriteFile((HANDLE) hTarget,
(LPCVOID) lpszData,
(DWORD) dwNumberOfBytesRead,
(LPDWORD) &dwNumberOfBytesWritten,
(LPOVERLAPPED) NULL);
dwFileBytePosition += dwNumberOfBytesRead;
}
else if (uCurrentState == CS_CORRUPT)
{
bResult = ReadFile( (HANDLE) hSource,
(LPVOID) lpszData,
(DWORD) dwNumberOfBytes,
(LPDWORD) &dwNumberOfBytesRead,
(LPOVERLAPPED) NULL);
if (bResult)
{
SetFilePointer( (HANDLE) hsFile,
(LONG) dwFileBytePosition,
(PLONG) NULL,
(DWORD) FILE_BEGIN);
uCurrentState = CS_PROCEED;
SendMessage(hsStatus, WM_SETTEXT, (WPARAM) NULL, (LPARAM) "Copying the file...");
return CF_SUCCESS;
}
bResult = WriteFile((HANDLE) hTarget,
(LPCVOID) ERROR_DATA,
(DWORD) dwNumberOfBytesRead,
(LPDWORD) NULL,
(LPOVERLAPPED) NULL);
dwFileBytePosition++;
}
if (dwFileBytePosition == dwFileSize) return CF_EOF;
return CF_SUCCESS;
}
//MessageBox(hWnd, "T", "C", MB_OK);

