PTDLGS.C
#include "porttool.h" 
#include "port.h" 
 
int DLGOFFSET = 100; 
 
RESULTrIssue; 
 
HANDLE    hBkFileHeap; 
extern HWND    hDlgPort; 
extern HWND    hDlgPortStatus; 
 
 
/* function prototypes for helper functions */ 
void WINAPI GrowDialog (HWND, BOOL); 
BOOL WINAPI GetHelpFileName (char *); 
BOOL WINAPI BuildFileList (char *, LPBKFILELIST *); 
BOOL WINAPI AddFile (char *, char *, BKFILELIST *); 
BOOL WINAPI RemoveFile (char *, LPBKFILELIST *); 
BOOL WINAPI FreeFileList (BKFILELIST *); 
 
BOOL MySetEvent (HWND hWnd, HANDLE hEvent); 
BOOL MyResetEvent (HWND hWnd, HANDLE hEvent); 
 
/* port options dialog */ 
BOOL WINAPI OptionsDlgProc ( 
    HWND    hDlg, 
    UINT    uMsg, 
    UINT    uParam, 
    LONG    lParam) 
{ 
BOOL       bRet = TRUE; 
static  DWORD      *dwPTFlags; 
static  HFONT      hStrikeoutFont; 
static  HFONT      hSystemFont; 
LOGFONT    lf; 
 
    switch (uMsg) 
{ 
case WM_INITDIALOG: 
    /* create strikeout font for ignored tokens */ 
    hSystemFont = GetStockObject (SYSTEM_FONT); 
    GetObject (hSystemFont, sizeof (LOGFONT), &lf); 
    lf.lfStrikeOut = TRUE; 
    hStrikeoutFont = CreateFontIndirect (&lf); 
 
    /* initialize token control with stock system font */ 
    SendMessage (GetDlgItem (hDlg, IDC_CURTOKEN), 
 WM_SETFONT, 
 (UINT)hSystemFont, 
 FALSE); 
 
    /* save dwPTFlags from lParam */ 
    dwPTFlags = (DWORD *)lParam; 
 
    /* initialize current token if any */ 
    if (*(WORD *)rIssue.lpszToken != MAXTOKENLEN) 
SetDlgItemText (hDlg, IDC_CURTOKEN, rIssue.lpszToken); 
    else 
EnableWindow (GetDlgItem (hDlg, IDC_IGNORETOKEN), FALSE); 
 
    /* initialize search flag check boxes */ 
    CheckDlgButton (hDlg, IDC_NOAPIS, (*dwPTFlags & PT_NOAPIS)); 
    CheckDlgButton (hDlg, IDC_NOMESSAGES, (*dwPTFlags & PT_NOMESSAGES)); 
    CheckDlgButton (hDlg, IDC_NOSTRUCTURES, (*dwPTFlags & PT_NOSTRUCTURES)); 
    CheckDlgButton (hDlg, IDC_NOMACROS, (*dwPTFlags & PT_NOMACROS)); 
    CheckDlgButton (hDlg, IDC_NOCONSTANTS, (*dwPTFlags & PT_NOCONSTANTS)); 
    CheckDlgButton (hDlg, IDC_NOTYPES, (*dwPTFlags & PT_NOTYPES)); 
    CheckDlgButton (hDlg, IDC_NOCUSTOM, (*dwPTFlags & PT_NOCUSTOM)); 
    CheckDlgButton (hDlg, IDC_IGNORECASE, (*dwPTFlags & PT_IGNORECASE)); 
 
    /* set focus to first check box, return FALSE */ 
    SetFocus (GetDlgItem (hDlg, IDC_NOAPIS)); 
    bRet = FALSE; 
    break; 
 
case WM_COMMAND: 
    switch (LOWORD (uParam)) 
{ 
case IDOK: 
    /* get check box states and return as FLAGS in UM_PORT message */ 
    *dwPTFlags = (*dwPTFlags & ~PT_IGNORECASE) ^ 
(IsDlgButtonChecked (hDlg, IDC_IGNORECASE) ? PT_IGNORECASE : 0); 
    *dwPTFlags = (*dwPTFlags & ~PT_NOAPIS) ^ 
(IsDlgButtonChecked (hDlg, IDC_NOAPIS) ? PT_NOAPIS : 0); 
    *dwPTFlags = (*dwPTFlags & ~PT_NOMESSAGES) ^ 
(IsDlgButtonChecked (hDlg, IDC_NOMESSAGES) ? PT_NOMESSAGES : 0); 
    *dwPTFlags = (*dwPTFlags & ~PT_NOSTRUCTURES) ^ 
(IsDlgButtonChecked (hDlg, IDC_NOSTRUCTURES) ? PT_NOSTRUCTURES : 0); 
    *dwPTFlags = (*dwPTFlags & ~PT_NOMACROS) ^ 
(IsDlgButtonChecked (hDlg, IDC_NOMACROS) ? PT_NOMACROS : 0); 
    *dwPTFlags = (*dwPTFlags & ~PT_NOCONSTANTS) ^ 
(IsDlgButtonChecked (hDlg, IDC_NOCONSTANTS) ? PT_NOCONSTANTS : 0); 
    *dwPTFlags = (*dwPTFlags & ~PT_NOTYPES) ^ 
(IsDlgButtonChecked (hDlg, IDC_NOTYPES) ? PT_NOTYPES : 0); 
    *dwPTFlags = (*dwPTFlags & ~PT_NOCUSTOM) ^ 
(IsDlgButtonChecked (hDlg, IDC_NOCUSTOM) ? PT_NOCUSTOM : 0); 
 
case IDCANCEL: 
    SendMessage (GetDlgItem (hDlg, IDC_CURTOKEN), WM_SETFONT, 0, FALSE); 
    DeleteObject (hStrikeoutFont); 
    EndDialog (hDlg, LOWORD (uParam) == IDOK); 
    break; 
 
case IDC_IGNORETOKEN: 
    /* toggle ignore bit */ 
    *dwPTFlags ^= PT_IGNORETOKEN; 
 
    /* have control draw in strikeout if ignored */ 
    if (*dwPTFlags & PT_IGNORETOKEN) 
SendMessage (GetDlgItem (hDlg, IDC_CURTOKEN), 
     WM_SETFONT, 
     (UINT)hStrikeoutFont, 
     TRUE); 
    /* else draw in system font */ 
    else 
SendMessage (GetDlgItem (hDlg, IDC_CURTOKEN), 
     WM_SETFONT, 
     (UINT)hSystemFont, 
     TRUE); 
    break; 
} 
    break; 
 
default: 
    bRet = FALSE; 
    break; 
} 
 
    /* return (message was processed); */ 
    return bRet; 
} 
 
 
 
/* port options dialog */ 
BOOL WINAPI PortDlgProc ( 
    HWND    hDlg, 
    UINT    uMsg, 
    UINT    uParam, 
    LONG    lParam) 
{ 
BOOL    bRet = TRUE; 
static  DWORD   dwPTFlags; 
static  BOOL    bSearching = TRUE; 
static  BOOL    bHelpActive = FALSE, bIsHelpFile = FALSE; 
static  HBRUSH  hBkBrush; 
static  HWND    hWndEdit; 
static  HANDLE  hEditData = NULL; 
static  int     nIssues = 0; 
static  int     iLineNo, iStartPos; 
static  HLOCAL  hToken, hHelp, hIssue, hSuggest; 
static  HLOCAL  hEditLine; 
 
static  UINT    uLen = 0; 
 
 
    switch (uMsg) 
{ 
case WM_INITDIALOG: 
    { 
    char    lpszTitle[MAX_PATH]; 
    char    lpszFilename[MAX_PATH]; 
    RECT    rc; 
 
    HDC     hDC; 
    HFONT   hFont; 
    TEXTMETRIC tm; 
 
    hFont = GetStockObject(SYSTEM_FONT); 
    hDC = GetDC(NULL); 
    hFont = SelectObject(hDC, hFont); 
    GetTextMetrics(hDC, &tm); 
    SelectObject(hDC, hFont); 
    ReleaseDC(NULL, hDC); 
    DLGOFFSET = tm.tmHeight * 5; 
 
    /* reposition self on bottom of screen */ 
    GetWindowRect (hDlg, &rc); 
    SetWindowPos (hDlg, 
  NULL, 
  rc.left, 
  GetSystemMetrics (SM_CYSCREEN) - 
   (rc.bottom - rc.top + DLGOFFSET), 
  rc.right-rc.left, 
  rc.bottom-rc.top, 
  SWP_NOZORDER | SWP_NOSIZE); 
 
    /* set help available flag */ 
    if (GetHelpFileName (lpszTitle)) 
{ 
EnableWindow (GetDlgItem (hDlg, IDC_HELPM), TRUE); 
bIsHelpFile = TRUE; 
} 
 
    /* allocate strings for Issue struct from local heap to reduce stack overhead */ 
    if (!(rIssue.lpszToken = LocalLock (hToken = LocalAlloc (LHND, MAXTOKENLEN))) || 
!(rIssue.lpszHelpStr = LocalLock (hHelp = LocalAlloc (LHND, MAXHELPLEN))) || 
!(rIssue.lpszIssue = LocalLock (hIssue = LocalAlloc (LHND, MAXISSUELEN))) || 
!(rIssue.lpszSuggest = LocalLock (hSuggest = LocalAlloc (LHND, MAXSUGGESTLEN)))) 
{ 
ErrorNotify (hDlg, IDS_MEMORYFAILED); 
PostMessage (hDlg, WM_COMMAND, IDC_DONE, 0); 
break; 
} 
    /* initialize line and token offset position stuff */ 
    iLineNo = 0; 
    iStartPos = 0; 
    rIssue.nPosToken = 0; 
 
    /* initialize background brush for use in WM_CTLCOLOR message */ 
    hBkBrush = (HBRUSH)GetClassLong (hDlg, GCL_HBRBACKGROUND); 
 
    /* set initial search flags to default */ 
    dwPTFlags = 0; 
 
    /* initialize filename in caption */ 
    LoadString (GetModuleHandle (NULL), IDS_PORTFILE, lpszTitle, MAX_PATH); 
    GetFileFromPath (lpszFilePath, lpszFilename); 
    strcat (lpszTitle, lpszFilename); 
    SetWindowText (hDlg, lpszTitle); 
 
    /* IDC_SUGGESTION to SW_HIDE */ 
    ShowWindow (GetDlgItem (hDlg, IDC_SUGGESTION), SW_HIDE); 
    ShowWindow (GetDlgItem (hDlg, IDC_SUGGESTLABEL), SW_HIDE); 
 
    /* get edit window and data handle */ 
    hWndEdit = (HWND)GetWindowLong (GetParent (hDlg), WL_HWNDEDIT); 
 
#if !defined (WIN32) 
 
    hEditData = (HANDLE)SendMessage (hWndEdit, EM_GETHANDLE, 0, 0); 
 
#else 
    { 
char    *lpEditData; 
char    sz[80]; 
MEMORYSTATUS memstat; 
 
uLen = GetWindowTextLength (hWndEdit); 
hEditData = LocalAlloc (LHND, uLen+1); 
if (hEditData == NULL) { 
    memstat.dwLength = sizeof(MEMORYSTATUS); 
    GlobalMemoryStatus (&memstat); 
    wsprintf (sz, "Failed Allocation: %u | %u (%u%%)", (UINT)uLen+1, (UINT)memstat.dwAvailPhys, memstat.dwMemoryLoad); 
    //MessageBox (GetFocus(), sz, "PortTool", MB_OK); 
    uLen = 500000; 
    while (hEditData == NULL && uLen > 1000) { 
uLen -= 1000; 
hEditData = LocalAlloc (LHND, uLen+1); 
    } 
    wsprintf (sz, "hEditData = %u : uLen = %u", (UINT)hEditData, (UINT)uLen); 
    //MessageBox (GetFocus(), sz, "PortTool", MB_OK); 
} 
lpEditData = LocalLock (hEditData); 
if (lpEditData == NULL) { 
    MessageBox (GetFocus(), "Unalble To Lock Memory!", "PortTool", MB_OK); 
} else { 
    UINT i; 
    i = GetWindowText (hWndEdit, lpEditData, uLen+1); 
    wsprintf (sz, "length: %u", i); 
    //MessageBox (GetFocus(), sz, "PortTool", MB_OK); 
} 
LocalUnlock (hEditData); 
    } 
#endif 
 
    /* allocate here, reallocate later when needed */ 
    hEditLine = LocalAlloc (LHND, 1); 
 
    /* post message to start ball rolling */ 
    PostMessage (hDlg, WM_COMMAND, (UINT)IDC_CONTINUE, 0); 
 
    /* don't worry about focus here since were going to drive the search anyway */ 
    bRet = TRUE; 
    } 
    //MessageBox (GetFocus(), "End Of Init", "PortTool", MB_OK); 
    break; 
 
case WM_COMMAND: 
    switch (LOWORD (uParam)) 
{ 
case IDC_CONTINUE: 
    { 
    int     iLastLine, nCharOffset, nLineLen; 
    MSG     msg; 
    char    lpszBuff[MAXTOKENLEN]; 
    char    *lpszLine; 
    char    *lpLine; 
    char    *lpEditData; 
 
    /* disable continue button */ 
    EnableWindow (GetDlgItem (hDlg, IDC_CONTINUE), FALSE); 
    EnableWindow (GetDlgItem (hDlg, IDC_OPTIONS), FALSE); 
    EnableWindow (GetDlgItem (hDlg, IDCANCEL), TRUE); 
 
    /* set IDC_SEARCHFOUND to green searching */ 
    LoadString (GetModuleHandle (NULL), IDS_SEARCHING, 
lpszBuff, 
sizeof (lpszBuff)); 
    SetWindowText (GetDlgItem (hDlg, IDC_SEARCHFOUND), lpszBuff); 
    bSearching = TRUE; 
 
    /* set last line */ 
    iLastLine = (int)SendMessage (hWndEdit, EM_GETLINECOUNT, 0, 0); 
 
    /* find next port issue */ 
    while (TRUE) 
{ 
if (iLineNo >= iLastLine) 
    { 
    /* no more issues found, so clean up and go away */ 
    ErrorNotify (hDlg, IDS_NOMOREPORTISSUES); 
 
    /* nullify any selection in line edit control */ 
    SendMessage (GetDlgItem (hDlg, IDC_LINE), EM_SETSEL, 0, 0); 
    break; 
    } 
 
/* increment line no */ 
SetWindowText (GetDlgItem (hDlg, IDC_LINENO), 
       itoa (iLineNo, lpszBuff, 10)); 
 
/* get length and number of edit line */ 
nCharOffset = SendMessage (hWndEdit, EM_LINEINDEX, iLineNo, 0); 
if ((nLineLen = SendMessage (hWndEdit, EM_LINELENGTH, nCharOffset, 0)) <= 2) 
    goto NEXT_LINE; 
 
/* allocate enough memory for edit line */ 
if (!(hEditLine = LocalReAlloc (hEditLine, 
nLineLen+1, 
LHND))) 
    { 
    /* no more issues found, so clean up and go away */ 
    ErrorNotify (hDlg, IDS_MEMORYFAILED); 
    PostMessage (hDlg, WM_COMMAND, IDC_DONE, 0); 
    break; 
    } 
 
/* get line from edit control, and null terminate */ 
 
/* get edit window and data handle */ 
 
lpEditData = LocalLock (hEditData); 
 
lpLine = lpszLine = LocalLock (hEditLine); 
 
strncpy (lpszLine, lpEditData+nCharOffset, nLineLen); 
lpszLine[nLineLen] = 0; 
 
/* increment the token position for multiple errors in a line */ 
lpLine += iStartPos; 
LocalUnlock (hEditData); 
 
/* initialize line and hilight token */ 
SetWindowText (GetDlgItem (hDlg, IDC_LINE), lpszLine); 
 
/* reinitialize rIssue strings lengths */ 
*(WORD *)rIssue.lpszToken = MAXTOKENLEN; 
*(WORD *)rIssue.lpszHelpStr = MAXHELPLEN; 
*(WORD *)rIssue.lpszIssue = MAXISSUELEN; 
*(WORD *)rIssue.lpszSuggest = MAXSUGGESTLEN; 
 
/* search next line */ 
if (CheckString (lpLine, dwPTFlags, &rIssue)) 
    { 
    /* set SEARCHFOUND string to found */ 
    LoadString (GetModuleHandle (NULL), 
IDS_FOUND, 
lpszBuff, 
sizeof (lpszBuff)); 
    strcat (lpszBuff, rIssue.lpszToken); 
    SetWindowText (GetDlgItem (hDlg, IDC_SEARCHFOUND), lpszBuff); 
 
    /* reenable options button */ 
    EnableWindow (GetDlgItem (hDlg, IDC_OPTIONS), TRUE); 
 
    /* set searching flag off */ 
    bSearching = FALSE; 
 
    /* increment issue cnt */ 
    SetWindowText (GetDlgItem (hDlg, IDC_ISSUECNT), 
   itoa (++nIssues, lpszBuff, 10)); 
 
    /* initialize Issue */ 
    SetWindowText (GetDlgItem (hDlg, IDC_ISSUE), rIssue.lpszIssue); 
 
    /* if help, enble button */ 
    EnableWindow (GetDlgItem (hDlg, IDC_HELPM), 
  ((*(rIssue.lpszSuggest) != 0) && bIsHelpFile)); 
 
    /* if suggest, show suggestion */ 
    if (*(rIssue.lpszSuggest)) 
{ 
SetWindowText (GetDlgItem (hDlg, IDC_SUGGESTION), 
       rIssue.lpszSuggest); 
if (!IsWindowVisible (GetDlgItem (hDlg, IDC_SUGGESTION))) 
    GrowDialog (hDlg, TRUE); 
} 
 
    else if (IsWindowVisible (GetDlgItem (hDlg, IDC_SUGGESTION))) 
GrowDialog (hDlg, FALSE); 
 
    /* scroll parent edit control and select offending text */ 
    SendMessage (hWndEdit, EM_LINESCROLL, 0, iLineNo - 
    SendMessage (hWndEdit, EM_GETFIRSTVISIBLELINE, 0, 0)); 
    SendMessage (hWndEdit, 
 EM_SETSEL, 
 iStartPos + nCharOffset + rIssue.nPosToken, 
 iStartPos + nCharOffset + rIssue.nPosToken + 
     strlen (rIssue.lpszToken)); 
 
    /* select text in line edit control */ 
    SendMessage (GetDlgItem (hDlg, IDC_LINE), 
 EM_SETSEL, 
 iStartPos + rIssue.nPosToken, 
 iStartPos + rIssue.nPosToken + 
     strlen (rIssue.lpszToken)); 
 
    /* reset nPosToken to check rest of line */ 
    iStartPos += (rIssue.nPosToken + strlen (rIssue.lpszToken)); 
    LocalUnlock (hEditLine); 
    break; 
    } 
 
/* call peek message to let user cancel if they choose */ 
if (PeekMessage (&msg, 
 GetDlgItem (hDlg, IDCANCEL), 
 WM_LBUTTONDOWN, 
 WM_LBUTTONDOWN, 
 PM_REMOVE)) 
    { 
    /* reset appropriate buttons */ 
    EnableWindow (GetDlgItem (hDlg, IDCANCEL), FALSE); 
    EnableWindow (GetDlgItem (hDlg, IDC_HELPM), FALSE); 
    EnableWindow (GetDlgItem (hDlg, IDC_OPTIONS), TRUE); 
 
    /* break to let message get delivered */ 
    break; 
    } 
 
/* also let the user exit from searching */ 
if (PeekMessage (&msg, 
 GetDlgItem (hDlg, IDC_DONE), 
 WM_LBUTTONDOWN, 
 WM_LBUTTONDOWN, 
 PM_REMOVE)) 
    { 
    PostMessage (hDlg, WM_COMMAND, IDC_DONE, 0); 
    break; 
    } 
 
/* unlock local edit line */ 
LocalUnlock (hEditLine); 
 
/* reset token position */ 
rIssue.nPosToken = 0; 
iStartPos = 0; 
NEXT_LINE: 
/* increment line and continue */ 
iLineNo++; 
} 
 
    /* enable continue button unless at end of file */ 
    if (iLineNo < iLastLine) 
{ 
EnableWindow (GetDlgItem (hDlg, IDC_CONTINUE), TRUE); 
SetFocus (GetDlgItem (hDlg, IDC_CONTINUE)); 
} 
    else 
{ 
EnableWindow (GetDlgItem (hDlg, IDC_CONTINUE), FALSE); 
EnableWindow (GetDlgItem (hDlg, IDCANCEL), FALSE); 
SetFocus (GetDlgItem (hDlg, IDC_DONE)); 
} 
    } 
    break; 
 
case WM_CLOSE: 
case IDC_DONE: 
    { 
    char    lpszFile[MAX_PATH]; 
 
    if (bHelpActive && 
GetHelpFileName (lpszFile)) 
WinHelp (hDlg, lpszFile, HELP_QUIT, 0); 
 
    /* clean up and go away */ 
    LocalUnlock (hToken); LocalFree (hToken); 
    LocalUnlock (hHelp); LocalFree (hHelp); 
    LocalUnlock (hIssue); LocalFree (hIssue); 
    LocalUnlock (hSuggest); LocalFree (hSuggest); 
    LocalFree (hEditLine); 
DestroyWindow (hDlg); 
hDlgPort = NULL; 
 
    } 
    break; 
 
case IDC_OPTIONS: 
    { 
    DWORD    dwOptions = dwPTFlags; 
 
    /* call dialog to start port process */ 
    if (DialogBoxParam (GetModuleHandle (NULL), 
IDD_OPTIONSDLG, 
hDlg, 
OptionsDlgProc, 
(LPARAM)&dwOptions)) 
{ 
dwPTFlags = dwOptions; 
 
/* if PT_IGNORETOKEN, call CheckString */ 
if (dwOptions & PT_IGNORETOKEN) 
    { 
    CheckString (rIssue.lpszToken, dwPTFlags, NULL); 
    dwPTFlags ^= PT_IGNORETOKEN; 
    } 
} 
 
    } 
    break; 
 
case IDC_HELPM: 
    { 
    char    lpszFile[MAX_PATH]; 
 
    if (bIsHelpFile && GetHelpFileName (lpszFile)) 
{ 
WinHelp (hDlg, lpszFile, HELP_KEY, (DWORD)rIssue.lpszHelpStr); 
bHelpActive = TRUE; 
} 
    } 
    break; 
 
case IDC_RESTART: 
    iLineNo = 0; 
    rIssue.nPosToken = 0; 
    iStartPos = 0; 
    PostMessage (hDlg, WM_COMMAND, IDC_CONTINUE, 0); 
    break; 
} 
    break; 
 
default: 
    bRet = FALSE; 
    break; 
} 
 
    /* return (message was processed); */ 
    return bRet; 
} 
 
 
 
 
/* background porting status dialog */ 
BOOL WINAPI BkPortDlgProc ( 
    HWND    hDlg, 
    UINT    uMsg, 
    UINT    uParam, 
    LONG    lParam) 
{ 
  BOOL          bRet = TRUE; 
  char          szFileName[MAX_PATH]; 
  char          szFilePath[MAX_PATH]; 
static    BKFILELIST    *lpbkFiles; 
static    int           iCurThread; 
static    BOOL          bStarted = FALSE; 
  BKFILELIST    *lpNode; 
 
//char szDebug[80]; 
 
// wsprintf (szDebug, "%i : [0x%X - 0x%X]", uMsg, uParam, lParam); 
// OutputDebugString (szDebug); 
 
    switch (uMsg) 
{ 
case WM_INITDIALOG: 
    { 
    HWND          hIssues = GetDlgItem (hDlg, IDC_ISSUES); 
    HWND          hLines = GetDlgItem (hDlg, IDC_LINES); 
    HWND          hComplete = GetDlgItem (hDlg, IDC_COMPLETE); 
 
    /* set background icon to porttool background icon and start minimized */ 
    SetClassLong (hDlg, 
  GCL_HICON, 
  (LONG)LoadIcon (GetModuleHandle (NULL), IDBkPort)); 
 
    lpbkFiles = NULL; 
    iCurThread = -1; 
 
    /* build list of files to port from lParam */ 
    if (lParam) 
{ 
if (!BuildFileList ((char *)lParam, &lpbkFiles)) 
    { 
    lpbkFiles = NULL; 
    break; 
    } 
} 
 
    else 
{ 
/* get file from user first */ 
*szFileName = 0; 
*szFilePath = 0; 
 
GetFileName (hDlg, szFileName, szFilePath); 
if (!BuildFileList (szFilePath, &lpbkFiles)) 
    { 
    lpbkFiles = NULL; 
    break; 
    } 
} 
 
    lpNode = lpbkFiles; 
    /* initialize each file in list */ 
    while (lpNode) 
{ 
/* add filename to listbox */ 
SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
     LB_ADDSTRING, 
     0, 
     (LPARAM)lpNode->bkFile.szFile); 
 
/* initialize some stuff */ 
lpNode->bkFile.hDlg = hDlg; 
lpNode->bkFile.dwPTFlags = PT_DEFAULT; 
 
/* start background thread on each file */ 
if (!StartBkPortThread (&lpNode->bkFile)) { 
    MessageBox(GetFocus(), "Failed to spawn background porting thread", "PortTool", MB_OK); 
} 
 
/* traverse list */ 
lpNode = lpNode->Next; 
} 
 
    /* select first thread in listbox */ 
    SendMessage (GetDlgItem (hDlg, IDC_FILELIST), LB_SETCURSEL, 0, 0); 
    SetDlgItemText (hDlg, IDC_FILEPATH, lpbkFiles->bkFile.szFilePath); 
 
    /* if started with /b switch */ 
    if (!GetParent (hDlg)) 
ShowWindow (hDlg, SW_SHOWMINIMIZED); 
    else 
MySetEvent (hDlg, lpbkFiles->hEvents[BKPORT_STATUS]); 
 
    iCurThread = 0; 
    bStarted = TRUE; 
} 
    break; 
 
case WM_SHOWWINDOW: 
    if (bStarted) 
{ 
int    i = 0; 
 
lpNode = lpbkFiles; 
while (i++ < iCurThread) 
    lpNode = lpNode->Next; 
 
if (!uParam && lpNode) 
    MyResetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]); 
else if(lpNode) 
    MySetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]); 
} 
    break; 
 
case WM_SIZE: 
    if (bStarted) { 
    int    i = 0; 
 
    lpNode = lpbkFiles; 
     
    while (i++ < iCurThread) { 
        lpNode = lpNode->Next; 
    } 
 
    if (uParam == SIZEICONIC && lpNode) { 
        MyResetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]); 
    } else if(lpNode) { 
        MySetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]); 
    } 
    } 
    break; 
 
case UM_STATUSUPDATE: 
    { 
    char    Buff[10]; 
 
    /* update status info controls */ 
    SetDlgItemText (hDlg, IDC_ISSUES, itoa (LOWORD (uParam), Buff, 10)); 
    SetDlgItemText (hDlg, IDC_COMPLETE, itoa (HIWORD (uParam), Buff, 10)); 
    SetDlgItemText (hDlg, IDC_LINES, itoa (lParam, Buff, 10)); 
    } 
    break; 
 
case UM_THREADCOMPLETE: 
    { 
    int    iThread = 0; 
 
    /* find handle in list */ 
    lpNode = lpbkFiles; 
    while (lpNode) 
{ 
if ((HANDLE)uParam == lpNode->bkFile.hThread) 
    break; 
lpNode = lpNode->Next; 
iThread++; 
} 
 
    if (lpNode) 
{ 
/* remove file list item */ 
RemoveFile (lpNode->bkFile.szFilePath, &lpbkFiles); 
 
/* remove item from list box */ 
SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
     LB_DELETESTRING, 
     iThread, 
     0); 
 
/* if current thread ended and more threads exist */ 
if (iThread == iCurThread && 
    lpbkFiles             && 
    SendMessage (GetDlgItem (hDlg, IDC_FILELIST), LB_GETCOUNT, 0, 0)) 
    { 
    SendMessage (GetDlgItem (hDlg, IDC_FILELIST), LB_SETCURSEL, 0, 0); 
    MySetEvent (hDlg, lpbkFiles->hEvents[BKPORT_STATUS]); 
    iCurThread = 0; 
    } 
 
else if (iThread == iCurThread) 
    { 
    iCurThread = -1; 
    PostMessage (hDlg, WM_COMMAND, IDC_BKDONE, 0); 
    } 
 
/* clean up controls */ 
SetDlgItemText (hDlg, IDC_FILEPATH, ""); 
PostMessage (hDlg, UM_STATUSUPDATE, 0, 0); 
} 
 
    else 
{ 
                CHAR szBuf[MAX_PATH]; 
                LoadString((HANDLE)GetModuleHandle(NULL), 
                    IDS_ERR_INVALID_THREADHND, 
                    szBuf,sizeof(szBuf)); 
MessageBox (hDlg, szBuf, NULL, MB_ICONSTOP | MB_OK); 
ExitProcess (FALSE); 
} 
 
    } 
    break; 
 
case WM_COMMAND: 
    switch (LOWORD (uParam)) 
{ 
case IDC_FILELIST: 
    /* if new file selected change update signal to active thread */ 
    if (HIWORD (uParam) == LBN_SELCHANGE) 
{ 
int    i = 0; 
int    iNewThread = SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
 LB_GETCURSEL, 
 0, 
 0); 
 
/* reset current thread */ 
lpNode = lpbkFiles; 
while (lpNode) 
    { 
    if (i == iCurThread) 
MyResetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]); 
 
    if (i == iNewThread) 
{ 
MySetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]); 
SetDlgItemText (hDlg, 
IDC_FILEPATH, 
lpNode->bkFile.szFilePath); 
} 
 
    lpNode = lpNode->Next; 
    i++; 
    } 
 
iCurThread = iNewThread; 
} 
    break; 
 
case IDC_ABORTFILE: 
    { 
    int        i = 0; 
    HCURSOR    hOldCursor; 
 
    /* reset current thread */ 
    lpNode = lpbkFiles; 
    while (lpNode) 
{ 
if (i == iCurThread) 
    { 
    /* put hourglass cursor up */ 
    hOldCursor = (HCURSOR)SetClassLong (hDlg, GCL_HCURSOR, 0); 
    SetCursor (LoadCursor (NULL, IDC_WAIT)); 
 
    /* abort porting file where it is */ 
    MySetEvent (hDlg, lpNode->hEvents[BKPORT_ABORT]); 
 
    /* remove file from list when thread is dead */ 
    WaitForSingleObject (lpNode->bkFile.hThread, INFINITE); 
    RemoveFile (lpNode->bkFile.szFilePath, &lpbkFiles); 
 
    /* replace original cursor */ 
    SetClassLong (hDlg, GCL_HCURSOR, (LONG)hOldCursor); 
    SetCursor (hOldCursor); 
 
    /* update listbox */ 
    SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
 LB_DELETESTRING, 
 iCurThread, 
 0); 
 
    /* select new event if any in listbox */ 
    if (SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
     LB_GETCOUNT, 
     0, 
     0)) 
{ 
SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
     LB_SETCURSEL, 
     0, 
     0); 
MySetEvent (hDlg, lpbkFiles->hEvents[BKPORT_STATUS]); 
iCurThread = 0; 
} 
 
    else 
{ 
iCurThread = -1; 
PostMessage (hDlg, WM_COMMAND, IDC_DONE, 0); 
} 
 
    /* clean up controls */ 
    SetDlgItemText (hDlg, IDC_FILEPATH, ""); 
    PostMessage (hDlg, UM_STATUSUPDATE, 0, 0); 
    break; 
    } 
 
lpNode = lpNode->Next; 
i++; 
} 
    } 
    break; 
 
case IDC_ADDFILE: 
    { 
    /* get file from user first */ 
    *szFileName = 0; 
    *szFilePath = 0; 
 
    /* add a file to the list */ 
    if (GetFileName (hDlg, szFileName, szFilePath)) 
{ 
/* if new list */ 
            if (!lpbkFiles) 
            { 
                if (!BuildFileList (szFilePath, &lpbkFiles)) 
                { 
                    lpbkFiles = NULL; 
                    break; 
                } 
            } 
else if (!AddFile (szFilePath, szFileName, lpbkFiles)) 
    break; 
 
/* find node in list */ 
lpNode = lpbkFiles; 
while (lpNode) 
    { 
    if (!strcmp (lpNode->bkFile.szFilePath, szFilePath)) 
break; 
    lpNode = lpNode->Next; 
    } 
 
if (lpNode) 
    { 
    /* add filename to listbox */ 
    SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
 LB_ADDSTRING, 
 0, 
 (LPARAM)lpNode->bkFile.szFile); 
 
    /* initialize some stuff */ 
    lpNode->bkFile.hDlg = hDlg; 
    lpNode->bkFile.dwPTFlags = PT_DEFAULT; 
 
    /* start background thread on this file */ 
    StartBkPortThread (&lpNode->bkFile); 
 
    /* if first thread */ 
    if (iCurThread == -1 || 
SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
     LB_GETCOUNT, 0, 0) == 1) 
{ 
iCurThread = 0; 
SendMessage (GetDlgItem (hDlg, IDC_FILELIST), 
     LB_SETCURSEL, 
     0, 
     0); 
SendMessage (hDlg, 
     WM_COMMAND, 
     MAKELONG (IDC_FILELIST, LBN_SELCHANGE), 
     0); 
} 
    } 
} 
    } 
    break; 
 
case IDC_CHANGEOPTIONS: 
    { 
    DWORD    dwFlags; 
 
dwFlags = 0L; 
    dwFlags = (dwFlags & ~PT_IGNORECASE) ^ 
(IsDlgButtonChecked (hDlg, IDC_BKIGNORECASE) ? PT_IGNORECASE : 0); 
    dwFlags = (dwFlags & ~PT_NOAPIS) ^ 
(IsDlgButtonChecked (hDlg, IDC_BKNOAPIS) ? PT_NOAPIS : 0); 
    dwFlags = (dwFlags & ~PT_NOMESSAGES) ^ 
(IsDlgButtonChecked (hDlg, IDC_BKNOMESSAGES) ? PT_NOMESSAGES : 0); 
    dwFlags = (dwFlags & ~PT_NOSTRUCTURES) ^ 
(IsDlgButtonChecked (hDlg, IDC_BKNOSTRUCTURES) ? PT_NOSTRUCTURES : 0); 
    dwFlags = (dwFlags & ~PT_NOMACROS) ^ 
(IsDlgButtonChecked (hDlg, IDC_BKNOMACROS) ? PT_NOMACROS : 0); 
    dwFlags = (dwFlags & ~PT_NOCONSTANTS) ^ 
(IsDlgButtonChecked (hDlg, IDC_BKNOCONSTANTS) ? PT_NOCONSTANTS : 0); 
    dwFlags = (dwFlags & ~PT_NOTYPES) ^ 
(IsDlgButtonChecked (hDlg, IDC_BKNOTYPES) ? PT_NOTYPES : 0); 
    dwFlags = (dwFlags & ~PT_NOCUSTOM) ^ 
(IsDlgButtonChecked (hDlg, IDC_BKNOCUSTOM) ? PT_NOCUSTOM : 0); 
 
    /* change the options for the file being ported */ 
    lpbkFiles->bkFile.dwPTFlags = dwFlags; 
    } 
    break; 
 
case IDCANCEL: 
    { 
    HCURSOR    hOldCursor; 
    HANDLE     hThreads[MAXBKTHREADS]; 
    int        i = 0; 
                    CHAR       szText[MAX_PATH]; // for LoadString() 
                    CHAR       szTitle[MAX_PATH]; // for LoadString() 
                    HMODULE    hModule = GetModuleHandle(NULL); 
 
    /* put up confirm message */ 
                    LoadString((HANDLE)hModule, 
                        IDS_CANCEL_BKGND_PROCESS, 
                        szText,sizeof(szText)); 
                    LoadString((HANDLE)hModule, 
                        IDS_ABORT_TITLE, 
                        szTitle,sizeof(szTitle)); 
    if (MessageBox (hDlg, 
    szText, szTitle, 
    MB_ICONQUESTION | MB_OKCANCEL) == IDOK) 
{ 
/* put hourglass cursor up */ 
hOldCursor = (HCURSOR)SetClassLong (hDlg, GCL_HCURSOR, 0); 
SetCursor (LoadCursor (NULL, IDC_WAIT)); 
 
/* if any files in list */ 
if (lpbkFiles) 
    { 
    /* abort all background threads and build thread handle array */ 
    lpNode = lpbkFiles; 
    while (lpNode) 
{ 
MySetEvent (hDlg, lpNode->hEvents[BKPORT_ABORT]); 
hThreads[i++] = lpNode->bkFile.hThread; 
lpNode = lpNode->Next; 
} 
 
    /* wait on completion of background threads */ 
    WaitForMultipleObjects (i, hThreads, TRUE, INFINITE); 
 
    /* free background port resources */ 
    FreeFileList (lpbkFiles); 
    } 
 
SetClassLong (hDlg, GCL_HCURSOR, (LONG)hOldCursor); 
SetCursor (hOldCursor); 
DestroyWindow (hDlg); 
hDlgPortStatus = NULL; 
 
} 
    } 
    break; 
 
case IDC_BKDONE: 
    /* if file list post message to cancel */ 
    if (lpbkFiles) 
PostMessage (hDlg, WM_COMMAND, IDCANCEL, 0); 
    else 
DestroyWindow (hDlg); 
hDlgPortStatus = NULL; 
    break; 
 
default: 
    bRet = FALSE; 
    break; 
} 
    break; 
 
case WM_DESTROY: 
    /* if no parent, post quit message */ 
    if (GetParent (hDlg) == NULL) 
PostQuitMessage (1); 
    break; 
 
default: 
    bRet = FALSE; 
    break; 
} 
 
    return bRet; 
} 
 
 
 
/* funtion retrieves the help filename from the ini file */ 
BOOL WINAPI GetHelpFileName ( 
    char    *lpszFile) 
{ 
    char        szAppName[30]; 
    char        szWinHelp[30]; 
    char        szDefault[] = "Default"; 
    OFSTRUCT    of; 
 
    /* get help filename from ini file */ 
    LoadString (GetModuleHandle (NULL), IDS_APPNAME, szAppName, 30); 
    LoadString (GetModuleHandle (NULL), IDS_WINHELP, szWinHelp, 30); 
    GetPrivateProfileString (szAppName, 
     szWinHelp, 
     szDefault, 
     lpszFile, 
     MAX_PATH, 
 lpszPortIniFilePath); 
 
    /* test to see if help file exists */ 
    return (OpenFile (lpszFile, &of, OF_EXIST) != -1); 
} 
 
 
 
 
/* rearrange dialog and controls */ 
void WINAPI GrowDialog ( 
    HWND    hDlg, 
    BOOL    bBigger) 
{ 
    RECT    rc; 
    int     nChange = (bBigger ? DLGOFFSET : -DLGOFFSET); 
 
    /* grow main dialog */ 
    GetWindowRect (hDlg, &rc); 
    SetWindowPos (hDlg, 
  NULL, 
  rc.left, 
  rc.top, 
  rc.right-rc.left, 
  rc.bottom-rc.top + nChange, 
  SWP_NOMOVE | SWP_NOZORDER); 
 
    /* move stop button down */ 
    GetWindowRect (GetDlgItem (hDlg, IDCANCEL), &rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc.right); 
    SetWindowPos (GetDlgItem (hDlg, IDCANCEL), 
  NULL, 
  rc.left, 
  rc.top + nChange, 
  rc.right-rc.left, 
  rc.bottom-rc.top, 
  SWP_NOSIZE | SWP_NOZORDER); 
 
    /* move CONTINUE button down */ 
    GetWindowRect (GetDlgItem (hDlg, IDC_CONTINUE), &rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc.right); 
    SetWindowPos (GetDlgItem (hDlg, IDC_CONTINUE), 
  NULL, 
  rc.left, 
  rc.top + nChange, 
  rc.right-rc.left, 
  rc.bottom-rc.top, 
  SWP_NOSIZE | SWP_NOZORDER); 
 
    /* move restart button down */ 
    GetWindowRect (GetDlgItem (hDlg, IDC_RESTART), &rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc.right); 
    SetWindowPos (GetDlgItem (hDlg, IDC_RESTART), 
  NULL, 
  rc.left, 
  rc.top + nChange, 
  rc.right-rc.left, 
  rc.bottom-rc.top, 
  SWP_NOSIZE | SWP_NOZORDER); 
 
    /* move options button down */ 
    GetWindowRect (GetDlgItem (hDlg, IDC_OPTIONS), &rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc.right); 
    SetWindowPos (GetDlgItem (hDlg, IDC_OPTIONS), 
  NULL, 
  rc.left, 
  rc.top + nChange, 
  rc.right-rc.left, 
  rc.bottom-rc.top, 
  SWP_NOSIZE | SWP_NOZORDER); 
 
    /* move help button down */ 
    GetWindowRect (GetDlgItem (hDlg, IDC_HELPM), &rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc.right); 
    SetWindowPos (GetDlgItem (hDlg, IDC_HELPM), 
  NULL, 
  rc.left, 
  rc.top + nChange, 
  rc.right-rc.left, 
  rc.bottom-rc.top, 
  SWP_NOSIZE | SWP_NOZORDER); 
 
    /* move done button down */ 
    GetWindowRect (GetDlgItem (hDlg, IDC_DONE), &rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc); 
    ScreenToClient (hDlg, (LPPOINT)&rc.right); 
    SetWindowPos (GetDlgItem (hDlg, IDC_DONE), 
  NULL, 
  rc.left, 
  rc.top + nChange, 
  rc.right-rc.left, 
  rc.bottom-rc.top, 
  SWP_NOSIZE | SWP_NOZORDER); 
 
    /* show suggestion edit control and label when appropriate */ 
    ShowWindow (GetDlgItem (hDlg, IDC_SUGGESTION), (bBigger ? SW_SHOW : SW_HIDE)); 
    ShowWindow (GetDlgItem (hDlg, IDC_SUGGESTLABEL), (bBigger ? SW_SHOW : SW_HIDE)); 
} 
 
 
 
 
BOOL WINAPI BuildFileList ( 
    char          *lpFileList, 
    LPBKFILELIST  *lpList) 
{ 
    char        *lpFile; 
    char        szFilePath[MAX_PATH]; 
    char        szFile[MAX_PATH]; 
    HFILE       hFile; 
    OFSTRUCT    of; 
    BOOL        bList = FALSE; 
 
    /* create heap for up to 50 files at a time */ 
    if (!(hBkFileHeap = HeapCreate (HEAP_NO_SERIALIZE, 
    sizeof (BKFILELIST), 
    MAXBKTHREADS * sizeof (BKFILELIST)))) 
return FALSE; 
 
    /* allocate first node in list */ 
    *lpList = (BKFILELIST *)HeapAlloc (hBkFileHeap, 0, sizeof (BKFILELIST)); 
    (*lpList)->hEvents[BKPORT_ABORT] = NULL; 
 
    /* parse first file in list */ 
    lpFile = strtok (lpFileList, " "); 
 
    /* loop through all files in list */ 
    while (lpFile) 
{ 
strcpy (szFilePath, lpFile); 
 
/* if no path, add current directory as path */ 
if (!GetFileFromPath (szFilePath, szFile)) 
    { 
    strcpy (szFile, szFilePath); 
    GetCurrentDirectory (MAX_PATH, szFilePath); 
    strcat (szFilePath, "\\"); 
    strcat (szFilePath, szFile); 
    } 
 
/* verify file is available */ 
hFile = OpenFile (szFilePath, &of, OF_READWRITE); 
if (hFile != -1) 
    { 
    /* added at least one file */ 
    bList = TRUE; 
 
    /* close file */ 
    CloseHandle ((HANDLE)hFile); 
 
    /* add file to list */ 
    AddFile (szFilePath, szFile, *lpList); 
    } 
 
/* get next file in list */ 
lpFile = strtok (NULL, " "); 
} 
 
    /* if no valid files, cleanup */ 
    if (!bList) 
{ 
HeapDestroy (hBkFileHeap); 
return FALSE; 
} 
 
    return TRUE; 
} 
 
 
 
 
BOOL WINAPI AddFile ( 
    char        *lpFilePath, 
    char        *lpFile, 
    BKFILELIST  *lpbkFiles) 
{ 
    BKFILELIST    *lpNode; 
 
 
    /* if first item in list don't need to allocate */ 
    if (!lpbkFiles->hEvents[BKPORT_ABORT]) 
lpNode = lpbkFiles; 
    else 
{ 
lpNode = (BKFILELIST *)HeapAlloc (hBkFileHeap, 0, sizeof (BKFILELIST)); 
if (!lpNode) 
    return FALSE; 
 
/* find end of list then add new node */ 
while (lpbkFiles->Next) 
    lpbkFiles = lpbkFiles->Next; 
lpbkFiles->Next = lpNode; 
} 
 
    /* initialize node structure */ 
    strcpy (lpNode->bkFile.szFile, lpFile); 
    strcpy (lpNode->bkFile.szFilePath, lpFilePath); 
    CreateEvents (lpNode->hEvents, &lpNode->bkFile); 
    lpNode->Next = NULL; 
 
    return TRUE; 
} 
 
 
 
 
BOOL WINAPI RemoveFile ( 
    char          *lpFilePath, 
    LPBKFILELIST  *lpbkFiles) 
{ 
    BKFILELIST    *pHead = *lpbkFiles; 
    BKFILELIST    *pTail = *lpbkFiles; 
 
    /* loop thru list until file name matches */ 
    while (pHead) 
{ 
if (!strcmp (lpFilePath, pHead->bkFile.szFilePath)) 
    { 
    /* special case remove first node */ 
    if (pTail == pHead) 
{ 
*lpbkFiles = pHead->Next; 
DestroyEvents (pHead->hEvents); 
HeapFree (hBkFileHeap, 0, (char *)(pHead)); 
 
/* if no more nodes, destroy heap */ 
if (!*lpbkFiles) 
    HeapDestroy (hBkFileHeap); 
} 
 
    else 
{ 
pTail->Next = pHead->Next; 
DestroyEvents (pHead->hEvents); 
HeapFree (hBkFileHeap, 0, (char *)pHead); 
} 
 
    return TRUE; 
    } 
 
pTail = pHead; 
pHead = pHead->Next; 
} 
 
    return FALSE; 
} 
 
 
 
 
BOOL WINAPI FreeFileList ( 
    BKFILELIST  *lpbkFiles) 
{ 
    /* loop thru each list item */ 
    while (lpbkFiles) 
{ 
/* destroy event handles */ 
DestroyEvents (lpbkFiles->hEvents); 
 
lpbkFiles = lpbkFiles->Next; 
} 
 
    /* release entire heap */ 
    HeapDestroy (hBkFileHeap); 
 
    return TRUE; 
} 
 
 
BOOL MySetEvent (HWND hWnd, HANDLE hEvent) 
{ 
    if (SetEvent(hEvent)) { 
return TRUE; 
    } else { 
return PostMessage (hWnd, (UINT)hEvent, 0, 0L); 
    } 
} 
 
BOOL MyResetEvent (HWND hWnd, HANDLE hEvent) 
{ 
    MSG msg; 
 
    if (ResetEvent(hEvent)) { 
return TRUE; 
    } else { 
PeekMessage (&msg, hWnd, (UINT)hEvent, (UINT)hEvent, TRUE); 
return TRUE; 
    } 
}