|
|
Microsoft Windows NT Build 511 (SDK Final Release) 07-24-1993
/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright (C) 1993 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
/*************************************************************************\
* PROGRAM: setinfo.c
*
* PURPOSE:
*
* To demonstrate queries and setting file information much as the
* OS/2 API's DosQFileInfo() and DosSetFileInfo().
*
* GLOBAL VARIABLES:
*
* HANDLE hInst; - Instance handle.
*
* HWND hWnd; - Client window handle.
*
* HWND hWndDlg;- Window handle to upper dialog box.
*
* HWND hWndFileDlg;
* - Window handle to lower dialog box.
*
* DWORD StepTime;
* - Time in ms., used to control the speed of reporting
* return codes in the upper dialog box.
*
* FUNCTIONS:
*
* WinMain() - Initializes the window, and process the message loop.
* MainWndProc() - To handle the messages to the main window.
* StatusDlgProc()- To handle messages to the Status Dialog (upper) box.
* FileDlgProc() - To handle messages to the File Dialog (lower) box.
* RepStat() - To calculate return codes and to send results as
* messages to the StatusDlgProc()
*
* COMMENTS:
*
* Overview:
* This sample captures and sets a files date/time, size, and
* attributes information (note it does not *set* file size
* information). It also reports API return code status
* information.
*
* To Use:
* Enter a file name into the appropriate edit field, and click on
* the Get Info. button. File information will be retrieved and
* placed in the various edit fields and check buttons. To set
* file information, modify the values in the Time and Date edit
* fields, and click the Set Info. button. To set file attributes,
* set the approprate check boxes, and click on the Set Attr. button.
* Note this application does not check for rediculous Date and Time
* information, and does not understand i.e. values before 1980 or after
* 2099. The API are left to deal with such values as best they
* can.
*
* As the buttons are clicked the code sends return code status
* information to be reported in the upper dialog box. The user
* can leave this reporting to be done at default time ( 0ms. Sleep
* between each API), or can enter a time in the appropriate box
* and clicking the Set Time button. This will put a Sleep between
* the API call so that the user can more easily read the return
* codes.
*
* Time Conversion:
* Note that GetFileTime() and SetFileTime() use 64 bit FILETIME
* structures. These structure consist of two DWORD fields: which
* represent file time in hundreds of nano-seconds. This file time
* can be converted into DosDate time (or back again) with the
* FileTimeToDosDateTime() and DosDateTimeToFileTime() calls. These
* calls use WORD values representing DosDate and DosTime. The
* online Windows .hlp files will tell you how these WORDs break
* down into days, months, hours, seconds, etc. This sample uses
* a combination of masking and shifting to extract the values
* from the file (see the FileDlgProc() and the symbolic constants
* mask defined in the header file). Other points of interest are
* that seconds are stored in 2 second increments (1-29), and that
* years are represented from 1980 (meaning i.e. 1992 will be
* be represented by 12).
*
*
\*************************************************************************/
#include <windows.h>
#include <stdlib.h>
#include "setinfo.h"
HANDLE hInst;
HWND hWnd, hWndDlg, hWndFileDlg;
DWORD StepTime;
/*************************************************************************\
*
* FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
*
* PURPOSE: Calls initialization function, processes message loop.
*
* COMMENTS: A fairly standard WinMain, with the exception that it
* creates two modeless dialog boxes which fit over the window.
* Note the use of IsDialogMessage in the message loop. This
* call not only returns a boolean value, but also processes
* the message if it is a dialog box message; otherwise the
* message falls through to the body of the loop to be translated
* and dispatched.
*
\*************************************************************************/
int APIENTRY WinMain (HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
WNDCLASS wc;
RECT rect;
UNREFERENCED_PARAMETER( lpCmdLine );
UNREFERENCED_PARAMETER( hPrevInstance );
hInst = hInstance;
wc.style = 0; // Replaces CS_SIZEREDRAW.
wc.lpfnWndProc = (WNDPROC)MainWndProc; // The client window procedure.
wc.cbClsExtra = 0; // No room reserved for extra data.
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = "";
wc.lpszClassName = "SetInfoWClass";
RegisterClass(&wc);
hWnd = CreateWindow ("SetInfoWClass",
"Set File Info. Sample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
hWndDlg = CreateDialog (hInst, "StatusDlg", hWnd, (DLGPROC)StatusDlgProc);
hWndFileDlg = CreateDialog (hInst, "FileDlg", hWnd, (DLGPROC)FileDlgProc);
GetClientRect (hWnd, &rect);
SendMessage (hWnd, WM_SIZE, 0, (rect.right - rect.left));
ShowWindow (hWndDlg, SW_SHOW);
ShowWindow (hWndFileDlg, SW_SHOW);
ShowWindow (hWnd, nCmdShow);
while (GetMessage (&msg, NULL, 0, 0))
if (!IsDialogMessage (hWndDlg, &msg)
&& !IsDialogMessage (hWndFileDlg, &msg))
{
DispatchMessage (&msg); // Dispatch message to window.
}
return (msg.wParam); // Returns value from PostQuitMessage.
}
/*************************************************************************\
*
* FUNCTION: MainWndProc (HWND, UINT, UINT, LONG)
*
* PURPOSE: To process messages. To launch client and server threads
* as appropriate.
*
* VARIABLES USED:
*
* - hWndDlg:
* Global window handle for the upper dialog box.
*
* - hWndFileDlg:
* Global window handle for the lower dialog box.
*
* MESSAGES:
*
* WM_DESTROY - Standard, destroys the window.
* WM_SIZE - Sends messages to the two dialog boxes so that they
* maintain their relative size to the client window.
*
* CALLED BY:
*
* WinMain();
*
\*************************************************************************/
LONG APIENTRY MainWndProc (HWND hwnd,
UINT message,
UINT wParam,
LONG lParam)
{
switch (message)
{
case WM_SIZE :
SetWindowPos (hWndDlg, NULL, 0,0, LOWORD(lParam), DIALOGHEIGHT, 0);
SetWindowPos (hWndFileDlg, NULL, 0,DIALOGHEIGHT, LOWORD(lParam), HIWORD(lParam), 0);
return (0);
case WM_DESTROY :
PostQuitMessage (0);
return (0);
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
/*************************************************************************\
*
* FUNCTION: StatusDlgProc (HWND, UINT, UINT, LONG)
*
* PURPOSE: To process messages for the upper dialog box.
*
* VARIABLES USED:
*
* - StepTime:
* A global DWORD holding the value of the sleep time between
* API calls.
*
* - bTranslated:
* A local BOOL needed for GetDlgItemInt().
*
* MESSAGES:
*
* WM_INITDIALOG: - Sets a "0" in the time edit field IDE_TIME. This
* is to indicate to the user that the default time
* set to sleep between reporting the results of
* API calls is set to 0.
*
* WM_REPSTAT: - A user defined message. This message uses wParam
* as a pointer to a string holding an API i.e.
* "CreateFile()". It uses lParam to hold a string
* reporting the value of returned by the API i.e.
* "ERROR_ACCESS_DENIED", or a number if the return
* value isn't identified in RepStat(). The code
* then places these strings in the IDE_API and
* IDE_REPSTAT edit fields.
*
* WM_COMMAND
*
* IDM_STEP: - Captures the time value in the IDE_TIME edit
* field, and then sets that value into the
* global DWORD StepTime. This value sets
* a sleep time inbetween reporting the results of
* each API (making it easier for the user to read).
*
* COMMENTS:
*
* This procedure controls the upper dialog box of the application.
* The purpose of this box is to report on the API being used by
* the lower box, and it's return code. It also allows you to control
* the speed that the application steps through these calls. This is
* basically a error checking/debugging feature, but it also lends an
* intuitive look at the API being used.
*
\*************************************************************************/
LONG APIENTRY StatusDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam)
{
BOOL bTranslated;
UNREFERENCED_PARAMETER (wParam);
UNREFERENCED_PARAMETER (lParam);
switch (message)
{
case WM_INITDIALOG:
StepTime = 0;
SetDlgItemInt (hDlg, IDE_TIME, StepTime, FALSE);
return (0);
case WM_REPSTAT:
SetDlgItemText (hDlg, IDE_API,(LPTSTR) wParam);
SetDlgItemText (hDlg, IDE_RETSTAT, (LPTSTR)lParam);
return (0);
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDB_STEP:
StepTime = GetDlgItemInt (hDlg, IDE_TIME, &bTranslated, FALSE);
}
}
return (0);
}
/*************************************************************************\
*
* FUNCTION: FileDlgProc (HWND, UINT, UINT, LONG)
*
* PURPOSE: To process the messages to the lower dialog box.
*
* VARIABLES USED:
*
* - fileName:
* A local CHAR array used to capture the text from the
* IDE_FILENAME edit field.
*
* - hFile: Local file handle.
*
* - retCode:
* Local DWORD used to trap API return codes.
*
* - ftCreation,
* - ftAccessed,
* - ftWrittenTo:
* Local FILETIME structures.
*
* - wDosDate,
* - wDosTime:
* Local WORDs, used to hold the values converted from the
* FILETIME structures converted by FileTimeToDosDateTime()
* and DosDateTimeToFileTime().
*
* - DD[],
* - MM[],
* - YY[],
* - Mn[],
* - SS[],
* - HH[]: Local CHAR arrays used to trap the values in various
* edit fields representing date and time values.
*
* - dwFileSize:
* Local DWORD holding file size.
*
* - lpsFileSize[]:
* Local CHAR array used to trap the string from the IDE_SIZE
* edit field.
*
* - dwFileAttr:
* Local DWORD holding the file attributes.
*
* - hDlg: Input parameter, handle to the dialog box.
*
* MESSAGES:
*
* WM_COMMAND
*
* IDB_ATTR:
* It initializes the variable to hold the file attributes,
* dwFileAttr, and then traps the checked states of the
* dialog boxes checked buttons. If a box is found to be
* checked, then the appropriate file attribute flag is
* OR'd into dwFileAttr. When all of the attribute values
* have been collected, these attributes are set to the file
* listed in IDE_FILENAME.
*
* IDB_SET:
* This collects the values from the various time and date
* edit fields, converts them into system time, and sets
* them to the file listed in IDE_FILENAME. Basically the
* technique is to 1) get the values from the edit fields;
* 2) shift them to their correct location in the WORD; and
* 3) OR them together into a single WORD.
*
* IDB_OPENFILE:
* This gets the date, time, size, and attribute information
* from the file listed in IDE_FILENAME. It converts the
* values appropriately and puts them into the various
* edit fields and check buttons. Again, to do time and date
* conversions, you must AND the values returned from
* GetFileTime() with certain masks to let the appropriate bits
* fall through from the WORD (see the mask and shift values
* in the setinfo.h file), and shift them to the low order
* bit to get the new values. This is done in the wsprintf()
* call's parameter list.
*
* CALLS TO:
*
* RepStat();
*
* COMMENTS:
* The basic function of this box is to capture and set file information,
* and to send messages to the upper dialog box via RepStat() to report
* return code information. Special characteristics of this function
* is how to get and set file information and attributes, and how to
* convert Time and Date information.
*
\*************************************************************************/
LONG APIENTRY FileDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam)
{
CHAR fileName[100];
HANDLE hFile;
DWORD retCode = 0;
FILETIME ftCreation, ftAccessed, ftWrittenTo;
WORD wDosDate, wDosTime;
CHAR DD[3], MM[3], YY[3], HH[3], Mn[3], SS[3];
DWORD dwFileSize;
CHAR lpsFileSize[10];
DWORD dwFileAttr;
UNREFERENCED_PARAMETER (wParam);
UNREFERENCED_PARAMETER (lParam);
switch (message)
{
case WM_COMMAND :
switch (LOWORD(wParam))
{
case IDB_ATTR:
dwFileAttr = 0;
if (IsDlgButtonChecked (hDlg, IDC_HIDE))
dwFileAttr |= FILE_ATTRIBUTE_HIDDEN;
if (IsDlgButtonChecked (hDlg, IDC_NORMAL))
dwFileAttr |= FILE_ATTRIBUTE_NORMAL;
if (IsDlgButtonChecked (hDlg, IDC_ARC))
dwFileAttr |= FILE_ATTRIBUTE_ARCHIVE;
if (IsDlgButtonChecked (hDlg, IDC_SYSTEM))
dwFileAttr |= FILE_ATTRIBUTE_SYSTEM;
if (IsDlgButtonChecked (hDlg, IDC_READ))
dwFileAttr |= FILE_ATTRIBUTE_READONLY;
GetDlgItemText (hDlg, IDE_FILENAME, fileName, 100);
retCode = SetFileAttributes (fileName, dwFileAttr);
RepStat ("SetFileAttributes()", retCode);
return (0);
case IDB_SET:
GetDlgItemText (hDlg, IDE_YEAR, YY, 3);
GetDlgItemText (hDlg, IDE_DAY, DD, 3);
GetDlgItemText (hDlg, IDE_MONTH, MM, 3);
wDosDate = (WORD)((atoi(YY) - 80)<<YRSHIFT |
atoi(MM)<<MONSHIFT |
atoi(DD)<<DAYSHIFT);
GetDlgItemText (hDlg, IDE_HOURS, HH, 3);
GetDlgItemText (hDlg, IDE_SECONDS, SS, 3);
GetDlgItemText (hDlg, IDE_MINUTES, Mn, 3);
wDosTime = (WORD)((atoi(SS) / 2)<< SECSHIFT |
atoi(Mn)<<MINSHIFT |
atoi(HH)<<HRSHIFT);
retCode = DosDateTimeToFileTime (wDosDate, wDosTime, &ftWrittenTo);
RepStat("DosDateTimeToFileTime()", retCode);
GetDlgItemText (hDlg, IDE_FILENAME, fileName, 100);
hFile = CreateFile (fileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (RepStat("CreateFile()", (DWORD)hFile))
return (0);
retCode = SetFileTime (hFile, NULL, NULL, &ftWrittenTo);
RepStat("SetFileTime()", retCode);
CloseHandle (hFile);
return (0);
case IDB_OPENFILE :
GetDlgItemText (hDlg, IDE_FILENAME, fileName, 100);
hFile = CreateFile (fileName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (RepStat("CreateFile()", (DWORD)hFile))
return (0);
(BOOL)retCode = GetFileTime (hFile,
&ftCreation,
&ftAccessed,
&ftWrittenTo);
RepStat( "GetFileTime()", retCode);
(BOOL)retCode = FileTimeToDosDateTime( &ftWrittenTo,
&wDosDate,
&wDosTime);
RepStat("FileTimeToDosDateTime()", retCode);
dwFileSize = GetFileSize (hFile, NULL);
RepStat("GetFileSize()", dwFileSize);
wsprintf(YY, "%02d", ((wDosDate & YRMASK) >> YRSHIFT ) + 80);
SetDlgItemText (hDlg, IDE_YEAR, YY);
wsprintf(MM, "%02d", ((wDosDate & MONMASK) >> MONSHIFT));
SetDlgItemText (hDlg, IDE_MONTH, MM);
wsprintf(DD, "%02d", ((wDosDate & DAYMASK) >> DAYSHIFT) );
SetDlgItemText (hDlg, IDE_DAY, DD);
wsprintf(SS, "%02d", ((wDosTime & SECMASK) >> SECSHIFT ) * 2);
SetDlgItemText (hDlg, IDE_SECONDS, SS);
wsprintf(Mn, "%02d", ((wDosTime & MINMASK) >> MINSHIFT));
SetDlgItemText (hDlg, IDE_MINUTES, Mn);
wsprintf(HH, "%02d", (DWORD)(wDosTime & HRMASK) >> HRSHIFT );
SetDlgItemText (hDlg, IDE_HOURS, HH);
wsprintf(lpsFileSize, "%d", dwFileSize);
SetDlgItemText (hDlg, IDE_SIZE, lpsFileSize);
dwFileAttr = GetFileAttributes (fileName);
RepStat("GetFileAttributes()", dwFileAttr);
if (dwFileAttr & FILE_ATTRIBUTE_NORMAL)
CheckDlgButton (hDlg, IDC_NORMAL, TRUE);
else
CheckDlgButton (hDlg, IDC_NORMAL, FALSE);
if (dwFileAttr & FILE_ATTRIBUTE_READONLY)
CheckDlgButton (hDlg, IDC_READ, TRUE);
else
CheckDlgButton (hDlg, IDC_READ, FALSE);
if (dwFileAttr & FILE_ATTRIBUTE_HIDDEN)
CheckDlgButton (hDlg, IDC_HIDE, TRUE);
else
CheckDlgButton (hDlg, IDC_HIDE, FALSE);
if (dwFileAttr & FILE_ATTRIBUTE_SYSTEM)
CheckDlgButton (hDlg, IDC_SYSTEM, TRUE);
else
CheckDlgButton (hDlg, IDC_SYSTEM, FALSE);
if (dwFileAttr & FILE_ATTRIBUTE_ARCHIVE)
CheckDlgButton (hDlg, IDC_ARC, TRUE);
else
CheckDlgButton (hDlg, IDC_ARC, FALSE);
CloseHandle (hFile);
return (0);
}
}
return (0);
}
/*************************************************************************\
*
* FUNCTION: RepStat (CHAR *, DWORD)
*
* PURPOSE: To report return code information to the upper dialog box.
*
* VARIABLES USED:
*
* - TempBufW[],
* - TempBufL[]:
* Local CHAR arrays used to set the lParam and wParam of
* the WM_REPSTAT message.
*
* - StepTime:
* Global DWORD representing the amount of sleep time chosen
* by the user.
*
* CALLED BY:
*
* FileDlgProc();
*
* COMMENTS:
*
* This function receives a string representing an API, and a DWORD
* representing it's return code value. It checks the return code to
* see if it indicates an error. If so, GetLastError is called to find
* the extended error information; if not, then retCode is set to 0.
* The case statement is used to exchange the retCode value for
* it's more intuitive string counterpart. If no counterpart
* is listed, the function just sends the number value in string
* form. Note that retCode 0 is just sent as a string number.
* Once the function drops from the switch statment, it sends the
* user define WM_REPSTAT message to the upper dialog box with the
* API and retCode information. It will then enter a Sleep of a
* duration determined by the global StepTime value (set by the
* user through and edit field. The function returns a boolean
* value so that the calling procedure can determine if it wants
* to continue processing or break.
*
\*************************************************************************/
BOOL RepStat (CHAR *API, DWORD retCode)
{
CHAR TempBufW[40];
CHAR TempBufL[40];
wsprintf(TempBufW, API);
if ((int)retCode <= 0 )
retCode = GetLastError();
else
retCode = 0;
if (retCode)
MessageBeep(0);
switch (retCode)
{
case ERROR_INVALID_FUNCTION: // 1L
wsprintf(TempBufL, "ERROR_INVALID_FUNCTION");
break;
case ERROR_FILE_NOT_FOUND: // 2L
wsprintf(TempBufL, "ERROR_FILE_NOT_FOUND");
break;
case ERROR_ACCESS_DENIED: // 5L
wsprintf(TempBufL, "ERROR_ACCESS_DENIED");
break;
case ERROR_INVALID_HANDLE: // 6L
wsprintf(TempBufL, "ERROR_INVALID_HANDLE");
break;
case ERROR_INVALID_PARAMETER: // 87L
wsprintf(TempBufL, "ERROR_INVALID_HANDLE");
break;
case ERROR_INVALID_NAME: // 123L
wsprintf(TempBufL, "ERROR_INVALID_NAME");
break;
default:
wsprintf(TempBufL, "%d", retCode);
}
SendMessage (hWndDlg, WM_REPSTAT, (DWORD)TempBufW, (LONG)TempBufL);
Sleep( StepTime );
return (retCode != 0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.