/* * WinCrypt password-encrypts and unencrypts files. First published in * PC Magazine, July, 1994. */ #include #include #include #include #include #include #include #include "wincrypt.h" #define KEYSIZE 512 #define BUFFERSIZE 8192 long FAR PASCAL WndProc (HWND, WORD, WORD, LONG); BOOL FAR PASCAL GetPasswordDlgProc (HWND, WORD, WORD, LONG); BOOL FAR PASCAL EncryptDlgProc (HWND, WORD, WORD, LONG); BOOL FAR PASCAL AboutDlgProc (HWND, WORD, WORD, LONG); void ODBDrawButton (DRAWITEMSTRUCT FAR *, HBITMAP, HBITMAP); void ODBChangeSelection (DRAWITEMSTRUCT FAR *); void ODBChangeFocus (DRAWITEMSTRUCT FAR *); void DrawButtonBorder (HDC, RECT *); int CopyFileNamesToListBox (HWND, int, char NEAR *); BOOL InitEncrypt (HWND, HINSTANCE); void Mutate (char NEAR *, char NEAR *, UINT, UINT); BOOL GetCell (char NEAR *, UINT, UINT, UINT); void SetCell (char NEAR *, UINT, UINT, UINT, BOOL); int Encrypt (char *, char NEAR *, char NEAR *, int); void InitGroupRect (HWND, int, RECT *, BOOL); void DrawGroupRect (HDC, RECT *); void PositionWindow (HWND); void SaveSettings (HWND); void CheckMessageQueue (void); void CenterDialog (HWND); char szIniFile[128]; // INI file name char szSection[] = "Settings"; // INI file section name char szEntry[] = "WindowPos"; // INI file entry names RECT rcGroup[2]; // Group coordinates HDROP hDrop; // Drop structure handle char szPassword[129] = ""; // Password char NEAR *npFileData; // Pointer to file I/O buffer char NEAR *npKey; // Pointer to encryption key char NEAR *npTmp; // Pointer to temporary buffer char *szError[] = { "WinCrypt Error", "There is not enough memory to run the application (LocalAlloc failed)", "There is not enough memory to copy the file names you selected to the "\ "list box (the combined length of the file names exceeds WinCrypt's "\ "8K buffer size)", "The Files list box is full" }; char *szFilter[] = { "All Files (*.*)", "*.*", "" }; /* * Function WinMain. */ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { static char szAppName[] = "WinCrypt"; WNDCLASS wndclass; HWND hwnd; MSG msg; if (!hPrevInstance) { wndclass.style = 0; wndclass.lpfnWndProc = (WNDPROC) WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = DLGWINDOWEXTRA; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (hInstance, szAppName); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; RegisterClass (&wndclass); } hwnd = CreateDialog (hInstance, szAppName, 0, NULL); InitGroupRect (hwnd, IDD_GROUP1, &rcGroup[0], TRUE); InitGroupRect (hwnd, IDD_GROUP2, &rcGroup[1], TRUE); ShowWindow (hwnd, nCmdShow == SW_SHOWMAXIMIZED ? SW_SHOW : nCmdShow); UpdateWindow (hwnd); while (GetMessage (&msg, NULL, 0, 0)) if (!IsDialogMessage (hwnd, &msg)) DispatchMessage (&msg); return msg.wParam; } /* * WndProc processes messages to the main window */ long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam) { static HINSTANCE hInstance; static HBRUSH hPatternBrush; static char NEAR *npFileNames; static OPENFILENAME ofn; static BOOL bFirstTime = TRUE; static HBITMAP hDisabledKey, hEnabledKey; FARPROC lpfnEncryptDlgProc, lpfnAboutDlgProc; int nFiles, nCount, nIndex, i; char szBuffer[128]; HBITMAP hBitmap; HDC hdc; HMENU hSysMenu; PAINTSTRUCT ps; POINT point; RECT rect; switch (message) { case WM_CREATE: // // Get ready! // hInstance = ((LPCREATESTRUCT) lParam)->hInstance; i = GetModuleFileName (hInstance, szIniFile, sizeof (szIniFile)); while (szIniFile[i--] != 0x2E); lstrcpy (&szIniFile[i+2], "INI"); if ((npFileData = (char NEAR *) LocalAlloc (LPTR, 3 * KEYSIZE)) == NULL) { MessageBox (hwnd, szError[IDERR_LOCALALLOCFAILED], szError[IDERR_TITLE], MB_ICONSTOP | MB_OK); return -1; } npKey = npFileData + KEYSIZE; npTmp = npKey + KEYSIZE; if ((npFileNames = (char NEAR *) LocalAlloc (LMEM_FIXED, BUFFERSIZE)) == NULL) { LocalFree ((HLOCAL) npFileData); MessageBox (hwnd, szError[IDERR_LOCALALLOCFAILED], szError[IDERR_TITLE], MB_ICONSTOP | MB_OK); return -1; } hPatternBrush = CreatePatternBrush (hBitmap = LoadBitmap (hInstance, "Background")); DeleteObject (hBitmap); hDisabledKey = LoadBitmap (hInstance, "DisabledKey"); hEnabledKey = LoadBitmap (hInstance, "EnabledKey"); hSysMenu = GetSystemMenu (hwnd, FALSE); DeleteMenu (hSysMenu, SC_SIZE, MF_BYCOMMAND); DeleteMenu (hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND); AppendMenu (hSysMenu, MF_SEPARATOR, 0, NULL); AppendMenu (hSysMenu, MF_STRING, IDM_ABOUT, "&About WinCrypt..."); DragAcceptFiles (hwnd, TRUE); PositionWindow (hwnd); return 0; case WM_PAINT: // // Repaint the window. // hdc = BeginPaint (hwnd, &ps); DrawGroupRect (hdc, &rcGroup[0]); DrawGroupRect (hdc, &rcGroup[1]); EndPaint (hwnd, &ps); return 0; case WM_ERASEBKGND: // // Paint the window background. // GetClientRect (hwnd, &rect); UnrealizeObject (hPatternBrush); point.x = point.y = 0; ClientToScreen (hwnd, &point); SetBrushOrg ((HDC) wParam, point.x, point.y); FillRect ((HDC) wParam, &rect, hPatternBrush); return 1; case WM_CTLCOLOR: // // Paint the control backgrounds light gray. // SetBkColor ((HDC) wParam, RGB (192, 192, 192)); return GetStockObject (LTGRAY_BRUSH); case WM_DRAWITEM: // // Paint the owner-draw Encrypt/Unencrypt button. // switch (((DRAWITEMSTRUCT FAR *) lParam)->itemAction) { case ODA_DRAWENTIRE: ODBDrawButton ((DRAWITEMSTRUCT FAR *) lParam, hDisabledKey, hEnabledKey); return TRUE; case ODA_SELECT: ODBChangeSelection ((DRAWITEMSTRUCT FAR *) lParam); return TRUE; case ODA_FOCUS: ODBChangeFocus ((DRAWITEMSTRUCT FAR *) lParam); return TRUE; } break; case WM_COMMAND: switch (wParam) { case IDD_FILES: // // Enable or disable the Delete File(s) button depending on // whether there are items highlighted in the list box. // if (HIWORD (lParam) == LBN_SELCHANGE) { EnableWindow (GetDlgItem (hwnd, IDD_DELETE), SendDlgItemMessage (hwnd, IDD_FILES, LB_GETSELCOUNT, 0, 0L) ? TRUE : FALSE); return 0; } break; case IDD_ADD: // // Let the user select files to add to the list box. // if (bFirstTime) { bFirstTime = FALSE; ofn.nFilterIndex = 0; } npFileNames[0] = 0; ofn.lStructSize = sizeof (OPENFILENAME); ofn.hwndOwner = hwnd; ofn.hInstance = NULL; ofn.lpstrFilter = szFilter[0]; ofn.lpstrCustomFilter = NULL; ofn.lpstrFile = (LPSTR) npFileNames; ofn.nMaxFile = BUFFERSIZE; ofn.lpstrFileTitle = NULL; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = "Select File(s)"; ofn.Flags = OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrDefExt = NULL; if (GetOpenFileName (&ofn)) { if (CopyFileNamesToListBox (hwnd, IDD_FILES, npFileNames)) MessageBox (hwnd, szError[IDERR_LISTBOXFULL], szError[IDERR_TITLE], MB_ICONINFORMATION | MB_OK); EnableWindow (GetDlgItem (hwnd, IDD_CLEAR), TRUE); EnableWindow (GetDlgItem (hwnd, IDD_ENCRYPT), TRUE); } else if (CommDlgExtendedError () == FNERR_BUFFERTOOSMALL) MessageBox (hwnd, szError[IDERR_NOTENOUGHMEMORY], szError[IDERR_TITLE], MB_ICONINFORMATION | MB_OK); return 0; case IDD_DELETE: // // Delete the selected file name(s) from the list box. // if (nFiles = (int) SendDlgItemMessage (hwnd, IDD_FILES, LB_GETSELCOUNT, 0, 0L)) { for (i=0; ihDC; CopyRect (&rect, &(lpdis->rcItem)); // // Fill the button interior with light gray and border the button with // a thin black line. // FillRect (hdc, &rect, GetStockObject (LTGRAY_BRUSH)); SelectObject (hdc, GetStockObject (BLACK_PEN)); MoveTo (hdc, rect.left + 1, rect.top); LineTo (hdc, rect.right - 1, rect.top); MoveTo (hdc, rect.right - 1, rect.top + 1); LineTo (hdc, rect.right - 1, rect.bottom - 1); MoveTo (hdc, rect.right - 2, rect.bottom - 1); LineTo (hdc, rect.left, rect.bottom - 1); MoveTo (hdc, rect.left, rect.bottom - 2); LineTo (hdc, rect.left, rect.top); // // Draw the raised button border. If the button has the input focus, // double the thickness of the black border and draw a focus rectangle. // InflateRect (&rect, -1, -1); if (lpdis->itemState & ODS_FOCUS) { FrameRect (hdc, &rect, GetStockObject (BLACK_BRUSH)); InflateRect (&rect, -7, -7); DrawFocusRect (hdc, &rect); InflateRect (&rect, 6, 6); } DrawButtonBorder (hdc, &rect); // // Draw the key on the face of the button. // CopyRect (&rect, &(lpdis->rcItem)); hdcMem = CreateCompatibleDC (hdc); hBitmap = (lpdis->itemState & ODS_DISABLED) ? hDisabledKey : hEnabledKey; hOldBitmap = SelectObject (hdcMem, hBitmap); GetObject (hBitmap, sizeof (bm), &bm); x = ((rect.right - rect.left) - bm.bmWidth) >>1 ; y = ((rect.bottom - rect.top) - bm.bmHeight) >> 1; BitBlt (hdc, x, y, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); SelectObject (hdcMem, hOldBitmap); DeleteDC (hdcMem); } /* * OBDChangeSelection redraws the Encrypt/Unencrypt button to reflect the * fact that it was just selected or deselected. * * Input parameters: * * lpdis = Pointer to DRAWITEMSTRUCT structure * * Returns: * * Nothing */ void ODBChangeSelection (DRAWITEMSTRUCT FAR *lpdis) { HDC hdc; RECT rect; HPEN hPen, hOldPen; hdc = lpdis->hDC; CopyRect (&rect, &(lpdis->rcItem)); if (lpdis->itemState & ODS_SELECTED) { // // Draw the button in its selected state. // InflateRect (&rect, -2, -2); FrameRect (hdc, &rect, GetStockObject (LTGRAY_BRUSH)); InflateRect (&rect, -1, -1); FrameRect (hdc, &rect, GetStockObject (LTGRAY_BRUSH)); InflateRect (&rect, 1, 1); hPen = CreatePen (PS_SOLID, 1, RGB (128, 128, 128)); hOldPen = SelectObject (hdc, hPen); MoveTo (hdc, rect.left, rect.bottom); LineTo (hdc, rect.left, rect.top); LineTo (hdc, rect.right, rect.top); DeleteObject (SelectObject (hdc, hOldPen)); InflateRect (&rect, -2, -2); BitBlt (hdc, rect.left + 1, rect.top + 1, rect.right - rect.left + 1, rect.bottom - rect.top + 1, hdc, rect.left, rect.top, SRCCOPY); } else { // // Draw the button in its unselected state. // InflateRect (&rect, -2, -2); DrawButtonBorder (hdc, &rect); InflateRect (&rect, -4, -4); BitBlt (hdc, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1, hdc, rect.left + 1, rect.top + 1, SRCCOPY); } } /* * OBDChangeFocus redraws the Encrypt/Unencrypt button to reflect the * fact that it just lost or gained the input focus. * * Input parameters: * * lpdis = Pointer to DRAWITEMSTRUCT structure * * Returns: * * Nothing */ void ODBChangeFocus (DRAWITEMSTRUCT FAR *lpdis) { HDC hdc; RECT rect; hdc = lpdis->hDC; CopyRect (&rect, &(lpdis->rcItem)); InflateRect (&rect, -1, -1); if (lpdis->itemState & ODS_FOCUS) { FrameRect (hdc, &rect, GetStockObject (BLACK_BRUSH)); InflateRect (&rect, -1, -1); } DrawButtonBorder (hdc, &rect); CopyRect (&rect, &(lpdis->rcItem)); InflateRect (&rect, -8, -8); DrawFocusRect (hdc, &rect); } /* * DrawButtonBorder draws the raised border of an owner-draw button. * * Input parameters: * * hdc = Device context handle * npRect = Pointer to RECT structure * * Returns: * * Nothing */ void DrawButtonBorder (HDC hdc, RECT *npRect) { SelectObject (hdc, CreatePen (PS_SOLID, 1, RGB (128, 128, 128))); MoveTo (hdc, npRect->left, npRect->bottom - 1); LineTo (hdc, npRect->right - 1, npRect->bottom - 1); LineTo (hdc, npRect->right - 1, npRect->top - 1); MoveTo (hdc, npRect->right - 2, npRect->top + 1); LineTo (hdc, npRect->right - 2, npRect->bottom - 2); LineTo (hdc, npRect->left, npRect->bottom - 2); DeleteObject (SelectObject (hdc, GetStockObject (WHITE_PEN))); MoveTo (hdc, npRect->left, npRect->bottom - 2); LineTo (hdc, npRect->left, npRect->top); LineTo (hdc, npRect->right - 1, npRect->top); MoveTo (hdc, npRect->right - 3, npRect->top + 1); LineTo (hdc, npRect->left + 1, npRect->top + 1); LineTo (hdc, npRect->left + 1, npRect->bottom - 2); } /* * CopyFileNamesToListBox copies the file name(s) returned by the * GetOpenFileName function to a list box. * * Input parameters: * * hwnd = Window handle * nListBoxID = List box ID * szFileList = Pointer to file list * * Returns: * * 0 = File names added * 1 = Error (list box is full) */ int CopyFileNamesToListBox (HWND hwnd, int nListBoxID, char NEAR *szFileList) { char szBuffer[128], szFileName[128]; int nEnd, i, j; // // Copy the path name to szBuffer and make sure the path ends in \. If // the path string is actually a file name, convert the file name to fully // qualified form, add the resulting string to the list box, and return. // i = 0; while ((szFileList[i] != 0x20) && (szFileList[i] != 0)) szBuffer[i] = szFileList[i++]; szBuffer[i] = 0; if (szFileList[i] == 0) { _fullpath (szFileName, szBuffer, sizeof (szFileName)); AnsiLower (szFileName); if (SendDlgItemMessage (hwnd, nListBoxID, LB_ADDSTRING, 0, (LPARAM) (LPCSTR) szFileName) == LB_ERRSPACE) { return 1; } return 0; } else { nEnd = i++; if (szBuffer[i - 2] != 0x5C) { szBuffer[i - 1] = 0x5C; szBuffer[i] = 0; nEnd++; } } // // Scan the remainder of the string and concatenate file names to the path // name, convert concatenated strings to fully qualified form, and add the // resulting strings to the list box. // while (szFileList[i] != 0) { j = nEnd; while ((szFileList[i] != 0x20) && (szFileList[i] != 0)) szBuffer[j++] = szFileList[i++]; if (szFileList[i] == 0x20) i++; szBuffer[j] = 0; _fullpath (szFileName, szBuffer, sizeof (szFileName)); AnsiLower (szFileName); if (SendDlgItemMessage (hwnd, nListBoxID, LB_ADDSTRING, 0, (LPARAM) (LPCSTR) szFileName) == LB_ERRSPACE) { return 1; } } return 0; } /* * InitEncrypt obtains a password from the user and generates an encryption * key from it. On return, npKey holds the key. * * Input parameters: * * hwnd = Window handle * hInstance = Instance handle * * Returns: * * TRUE = Proceed with the encryption process (user clicked OK) * FALSE = Do not proceed with the encryption process (user clicked Cancel) */ BOOL InitEncrypt (HWND hwnd, HINSTANCE hInstance) { FARPROC lpfnGetPasswordDlgProc; int nPasswordLength, nResult, nCount, i, j; // // Ask the user to enter a password. // lpfnGetPasswordDlgProc = MakeProcInstance (GetPasswordDlgProc, hInstance); nResult = DialogBox (hInstance, "GetPassword", hwnd, lpfnGetPasswordDlgProc); FreeProcInstance (lpfnGetPasswordDlgProc); if (!nResult) return FALSE; // // Replicate the password enough times to fill the key. // nPasswordLength = lstrlen (szPassword); i = 0; while (i < KEYSIZE) { nCount = min (nPasswordLength, KEYSIZE - i); j = 0; while (j < nCount) npKey[i++] = szPassword[j++]; } // // Generate a series of "mutated" numbers from the key using a simple // (but non-reversible) one-step cellular automaton process, and XOR the // series into the key. Note: The numeric parameters passed to the Mutate // function assume a 512-byte key size. If KEYSIZE changes, this statement // must be changed, too! // Mutate (npKey, npTmp, 64, 64); i = 0; while (i < KEYSIZE) npKey[i] ^= npTmp[i++]; // // Generate a series of random numbers and XOR the series into the key. // i = j = 0; while (i < nPasswordLength) j += (int) szPassword[i++]; srand (j); i = 0; while (i < KEYSIZE) npKey[i++] ^= (char) (rand () % 0x100); return TRUE; } /* * Mutate generates a mutated key from an input key using a cellular * automaton process similar to the one that drives John Conway's Life, * which was described in the October 1970 issue of Scientific American. * Each bit in the input key represents a "cell" in a grid, and each cell * is set to 1 or 0 according to its current state and the states of its * neighbors. * * Input parameters: * * npInputKey = Pointer to input key * npOutputKey = Pointer to output key * nWidth = Grid width (in cells) * nHeight = Grid height (in cells) * * Returns: * * Nothing * * Note: * * (nWidth * nHeight) must equal the key size in bits! */ void Mutate (char NEAR *npInputKey, char NEAR *npOutputKey, UINT nWidth, UINT nHeight) { BOOL bCurrentCellAlive; UINT nLastRow, nNextRow, nLastCol, nNextCol; UINT i, j, nNeighbors; for (i=0; i> 3; return (*(npGrid + nByteNumber) & (1 << nBitNumber)) ? TRUE : FALSE; } /* * SetCell is called by Mutate to set a cell value to 0 or 1. * * Input parameters: * * npGrid = Pointer to grid * i = Cell's column number * j = Cell's row number * bCellState = New cell value (TRUE=1, FALSE=0) * * Returns: * * Nothing */ void SetCell (char NEAR *npGrid, UINT nWidth, UINT i, UINT j, BOOL bCellState) { UINT nByteNumber, nBitNumber; nBitNumber = ((j * nWidth) + i) & 7; nByteNumber = ((j * nWidth) + i) >> 3; if (bCellState) *(npGrid + nByteNumber) |= (1 << nBitNumber); else *(npGrid + nByteNumber) &= (~(1 << nBitNumber)); } /* * Encrypt encrypts or unencrypts a file. * * Input parameters: * * szFileName = Pointer to name of file to encrypt * npFileData = Pointer to buffer for file data * npKey = Pointer to encryption key * nKeySize = Key size (in bytes) * * Returns: * * 0 = File was successfully encrypted or unencrypted * 1 = File was not found or could not be opened * 2 = Error reading file * 3 = Error writing file * * Notes: * * This function assumes that the key size and file I/O buffer size * are the same. File data is read nKeySize bytes at a time, XORed with * the corresponding characters in the encryption key, and written back * to disk. */ int Encrypt (char *szFileName, char NEAR *npFileData, char NEAR* npKey, int nKeySize) { HFILE hFile; UINT nBytesToRead, nBytesRead, i; UINT nBytesToWrite, nBytesWritten; DWORD dwBytesRemaining; // // Open the file for reading and writing. // if ((hFile = _lopen (szFileName, READ_WRITE)) == HFILE_ERROR) return 1; // // Determine the file size. // dwBytesRemaining = (DWORD) _llseek (hFile, 0, 2); _llseek (hFile, 0, 0); // // Encrypt or unencrypt the file. // while (dwBytesRemaining) { nBytesToRead = min (nKeySize, dwBytesRemaining); nBytesRead = _lread (hFile, npFileData, nBytesToRead); if (nBytesRead != nBytesToRead) { _lclose (hFile); return 2; } for (i=0; ileft); ScreenToClient (hwnd, (POINT FAR *) &rect->right); if (bDestroy) DestroyWindow (GetDlgItem (hwnd, nID)); } /* * DrawGroupRect draws a recessed group rectangle at the specified location. * * Input parameters: * * hdc = Device context handle * rect = Pointer to RECT structure containing the rectangle's coordinates * * Returns: * * Nothing */ void DrawGroupRect (HDC hdc, RECT *rect) { HPEN hPen; FillRect (hdc, rect, GetStockObject (LTGRAY_BRUSH)); hPen = CreatePen (PS_SOLID, 1, RGB (128, 128, 128)); SelectObject (hdc, hPen); MoveTo (hdc, rect->left, rect->bottom - 1); LineTo (hdc, rect->left, rect->top); LineTo (hdc, rect->right, rect->top); DeleteObject (SelectObject (hdc, GetStockObject (WHITE_PEN))); MoveTo (hdc, rect->right - 1, rect->top + 1); LineTo (hdc, rect->right - 1, rect->bottom - 1); LineTo (hdc, rect->left, rect->bottom - 1); } /* * PositionWindow positions the window on the screen using the * WindowPos entry stored in WINCRYPT.INI. If WINCRYPT.INI does not * exist, if it does exist but does not contain a WindowPos entry, or * if WindowPos specifies a position that is off (or nearly off) the * screen, PositionWindows centers the window on the screen. * * Input parameters: * * hwnd = Window handle * * Returns: * * Nothing */ void PositionWindow (HWND hwnd) { char szBuffer[32]; static char szDefString[] = "WindowPos=32767,32767"; int cxWindowPos, cyWindowPos, cxScreenSize, cyScreenSize; RECT rect; GetPrivateProfileString (szSection, szEntry, szDefString, szBuffer, sizeof (szBuffer), szIniFile); sscanf (szBuffer, "%u,%u", &cxWindowPos, &cyWindowPos); cxScreenSize = GetSystemMetrics (SM_CXSCREEN); cyScreenSize = GetSystemMetrics (SM_CYSCREEN); if ((cxWindowPos > (cxScreenSize - 32)) || (cyWindowPos > (cyScreenSize - 32))) { GetWindowRect (hwnd, &rect); cxWindowPos = (cxScreenSize - (rect.right - rect.left)) >> 1; cyWindowPos = (cyScreenSize - (rect.bottom - rect.top)) >> 1; } SetWindowPos (hwnd, 0, cxWindowPos, cyWindowPos, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } /* * SaveSettings saves program settings to WINCRYPT.INI. * * Input parameters: * * hwnd = Window handle * * Returns: * * Nothing */ void SaveSettings (HWND hwnd) { WINDOWPLACEMENT wp; char szBuffer[32]; wp.length = sizeof (wp); GetWindowPlacement (hwnd, &wp); wsprintf (szBuffer, "%u,%u", (wp.rcNormalPosition).left, (wp.rcNormalPosition).top); WritePrivateProfileString (szSection, szEntry, szBuffer, szIniFile); } /* * CheckMessageQueue flushes the application message queue. * * Input parameters: * * None * * Returns: * * Nothing */ void CheckMessageQueue (void) { MSG msg; while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { GetMessage (&msg, NULL, 0, 0); DispatchMessage (&msg); } } /* * CenterDialog centers a dialog box window (or any window, for that matter) * on the screen. * * Input parameters: * * hwnd = Window handle * * Returns: * * Nothing */ void CenterDialog (HWND hwnd) { RECT rect; GetWindowRect (hwnd, &rect); SetWindowPos (hwnd, 0, (GetSystemMetrics (SM_CXSCREEN) - (rect.right - rect.left)) >> 1, (GetSystemMetrics (SM_CYSCREEN) - (rect.bottom - rect.top)) >> 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } /* * GetPasswordDlgProc processes messages to the Get Password dialog box. */ BOOL FAR PASCAL GetPasswordDlgProc (HWND hwnd, WORD message, WORD wParam, LONG lParam) { int nCount; BOOL bButtonEnabled; switch (message) { case WM_INITDIALOG: // // Initialize the edit control and the OK button and center the dialog // box on the screen if the main window is minimized. // if (IsIconic (GetWindow (hwnd, GW_OWNER))) CenterDialog (hwnd); SendDlgItemMessage (hwnd, IDD_PASSWORD, EM_LIMITTEXT, sizeof (szPassword) - 1, 0L); return TRUE; case WM_COMMAND: switch (wParam) { case IDD_PASSWORD: // // Enable the OK button if the edit control contains at least // one character of text, or disable the button if the control // is empty. // if (HIWORD (lParam) == EN_CHANGE) { nCount = (int) SendDlgItemMessage (hwnd, IDD_PASSWORD, EM_LINELENGTH, 0, 0L); bButtonEnabled = IsWindowEnabled (GetDlgItem (hwnd, IDOK)); if ((nCount == 0) && bButtonEnabled) EnableWindow (GetDlgItem (hwnd, IDOK), FALSE); else if ((nCount != 0) && !bButtonEnabled) EnableWindow (GetDlgItem (hwnd, IDOK), TRUE); return TRUE; } break; case IDOK: // // Get the password, dismiss the dialog box, and return 1 as a // signal to proceed. // GetDlgItemText (hwnd, IDD_PASSWORD, szPassword, sizeof (szPassword)); EndDialog (hwnd, 1); return TRUE; case IDCANCEL: // // Dismiss the dialog box and return 0 to cancel the encryption // process. // EndDialog (hwnd, 0); return TRUE; } break; } return FALSE; } /* * EncryptDlgProc processes messages to the Encrypt dialog box. * * Note: * * The global variable hDrop determines whether this function obtains file * names from a drop structure or the Files list box. If hDrop is nonzero, * file names are retrieved from the drop structure referenced by hDrop. * If hDrop is 0, file names are retrieved from the list box. */ BOOL FAR PASCAL EncryptDlgProc (HWND hwnd, WORD message, WORD wParam, LONG lParam) { static char *szEncError[] = { ". Do you want to continue?", "Error opening ", "Error reading ", "Error writing " }; char szFileName[128], szBuffer[192]; static BOOL bQuit, bDone; int nResult, nFiles, i; switch (message) { case WM_INITDIALOG: // // Initialize the dialog box and kick off the encryption process by // posting an IDOK notification to ourself. // if (IsIconic (GetWindow (hwnd, GW_OWNER))) CenterDialog (hwnd); PostMessage (hwnd, WM_COMMAND, IDOK, 0L); bQuit = bDone = FALSE; return TRUE; case WM_COMMAND: switch (wParam) { case IDOK: // // Encrypt or unencrypt the file(s). // if (bDone) EndDialog (hwnd, 0); else { nFiles = hDrop ? DragQueryFile (hDrop, -1, NULL, 0) : (int) SendDlgItemMessage (GetWindow (hwnd, GW_OWNER), IDD_FILES, LB_GETCOUNT, 0, 0L); i = 0; while ((i < nFiles) && !bQuit) { if (hDrop) { DragQueryFile (hDrop, i, szFileName, sizeof (szFileName)); AnsiLower (szFileName); } else SendDlgItemMessage (GetWindow (hwnd, GW_OWNER), IDD_FILES, LB_GETTEXT, (WPARAM) i, (LPARAM) (LPCSTR) szFileName); SetDlgItemText (hwnd, IDD_CURRENTFILE, szFileName); nResult = Encrypt (szFileName, npFileData, npKey, KEYSIZE); if (nResult) { lstrcpy (szBuffer, szEncError[nResult]); lstrcat (szBuffer, szFileName); lstrcat (szBuffer, szEncError[0]); if (MessageBox (hwnd, szBuffer, szError[IDERR_TITLE], MB_ICONQUESTION | MB_YESNO) == IDNO) { EndDialog (hwnd, 0); return TRUE; } } i++; } if (bQuit) EndDialog (hwnd, 0); else { bDone = TRUE; SetDlgItemText (hwnd, IDD_CURRENTFILE, "Done!"); SetDlgItemText (hwnd, IDCANCEL, "OK"); } } return TRUE; case IDCANCEL: // // Set the bQuit flag to end the process. // if (bDone) EndDialog (hwnd, 0); else bQuit = TRUE; return TRUE; } break; } return FALSE; } /* * AboutDlgProc processes messages to the About WinCrypt dialog box. */ BOOL FAR PASCAL AboutDlgProc (HWND hwnd, WORD message, WORD wParam, LONG lParam) { static HPEN hPen; static RECT rectFrame; static HFONT hDlgFont; PAINTSTRUCT ps; LOGFONT lf; RECT rect; HDC hdc; switch (message) { case WM_INITDIALOG: // // Initialize and create GDI objects. // InitGroupRect (hwnd, IDD_FRAME, &rectFrame, TRUE); if (IsIconic (GetWindow (hwnd, GW_OWNER))) CenterDialog (hwnd); GetObject ((HFONT) SendMessage (hwnd, WM_GETFONT, 0, 0L), sizeof (LOGFONT), &lf); lstrcpy (lf.lfFaceName, "Arial"); lf.lfHeight *= 3; lf.lfWidth *= 3; lf.lfItalic = 1; lf.lfOutPrecision = OUT_TT_PRECIS; if ((hDlgFont = CreateFontIndirect ((LPLOGFONT) &lf)) != NULL) SendDlgItemMessage (hwnd, IDD_TITLE, WM_SETFONT, hDlgFont, 0L); hPen = CreatePen (PS_SOLID, 1, RGB (128, 128, 128)); return TRUE; case WM_CTLCOLOR: // // Paint all control backgrounds light gray. Also change the title // color to bright red. // SetBkColor ((HDC) wParam, RGB (192, 192, 192)); if (GetDlgCtrlID (LOWORD (lParam)) == IDD_TITLE) SetTextColor ((HDC) wParam, RGB (255, 0, 0)); return GetStockObject (LTGRAY_BRUSH); case WM_ERASEBKGND: // // Paint the window background light gray. // GetClientRect (hwnd, &rect); FillRect ((HDC) wParam, &rect, GetStockObject (LTGRAY_BRUSH)); return TRUE; case WM_PAINT: // // Draw the rectangle surrounding the dialog box text. // hdc = BeginPaint (hwnd, &ps); SelectObject (hdc, hPen); SelectObject (hdc, GetStockObject (NULL_BRUSH)); Rectangle (hdc, rectFrame.left, rectFrame.top, rectFrame.right, rectFrame.bottom); SelectObject (hdc, GetStockObject (WHITE_PEN)); Rectangle (hdc, rectFrame.left + 1, rectFrame.top + 1, rectFrame.right + 1, rectFrame.bottom + 1); EndPaint (hwnd, &ps); return TRUE; case WM_COMMAND: // // Dismiss the dialog box in response to an IDOK or IDCANCEL message. // switch (wParam) { case IDOK: case IDCANCEL: EndDialog (hwnd, 0); return TRUE; } break; case WM_DESTROY: // // Delete GDI objects. // if (hDlgFont != NULL) DeleteObject (hDlgFont); DeleteObject (hPen); return TRUE; } return FALSE; }