free(Val);
RegCloseKey(hSubK);
return TRUE;
}
BOOL DisplayPair(LPTSTR ValueName, DWORD ValueType, LPBYTE Value, DWORD ValueLen, LPBOOL Flags)
/* Функция, отображающая пары "имя-значение". */
{
LPBYTE pV = Value;
DWORD i;
_tprintf(_T("\nValue: %s = "), ValueName);
switch (ValueType) {
case REG_FULL_RESOURCE_DESCRIPTOR: /* 9: описание оборудования. */
case REG_BINARY: /* 3: Любые двоичные данные. */
for (i = 0; i < ValueLen; i++, pV++) _tprintf (_T (" %x"), *pV);
break;
case REG_DWORD: /* 4: 32-битовое число. */
_tprintf(_T ("%x"), (DWORD)*Value);
break;
case REG_MULTI SZ: /*7: массив строк, завершающихся нулевым символом.*/
case REG_SZ: /* 1: строка, завершающаяся нулевым символом. */
_tprintf(_T("%s"), (LPTSTR)Value);
break;
/* … Несколько других типов … */
}
return TRUE;
}
BOOL DisplaySubKey(LPTSTR KeyName, LPTSTR SubKeyName, PFILETIME pLastWrite, LPBOOL Flags) {
BOOL Long = Flags[1];
SYSTEMTIME SysLastWrite;
_tprintf(_T("\nSubkey: %s"), KeyName);
if (_tcslen(SubKeyName) > 0) _tprintf (_T ("\\%s "), SubKeyName);
if (Long) {
FileTimeToSystemTime(pLastWrite, &SysLastWrite);
_tprintf(_T("%02d/%02d/%04d %02d:%02d:%02d"), SysLastWrite.wMonth, SysLastWrite.wDay, SysLastWrite.wYear, SysLastWrite.wHour, SysLastWrite.wMinute, SysLastWrite.wSecond);
}
return TRUE;
}
Резюме
В главах 2 и 3 описаны все наиболее важные базовые функции, необходимые для работы с файлами, каталогами и консольным вводом/выводом. Использование этих функций для построения типичных приложений иллюстрировали многочисленные примеры. Как показывает последний из примеров, между управлением системным реестром и управлением файловой системой имеется много общего.
В последующих главах будут рассмотрены такие усовершенствованные методы ввода/вывода, как асинхронные операции ввода/вывода и отображение файлов. Этих средств будет достаточно для того, чтобы воспроизвести в Windows почти любой из обычных видов обработки файлов, доступных при использовании UNIX или библиотечных функций С.
В приложении Б приведены сравнительные таблицы функций Windows, UNIX и библиотеки С, в которых наглядно показано, в чем указанные группы функций соответствуют друг другу, а в чем заметно отличаются.
В следующих главах
Глава 4 рассказывает о том, как упростить обработку ошибок и исключений, и распространяет применение функции ReportError на случаи обработки любых исключительных ситуаций.
Дополнительная литература
Для получения более подробной информации относительно программирования и использования системного реестра Windows, обратитесь к книге [17].
Упражнения
3.1. Используя функции GetDiskFreeSpace и GetDiskFreeSpaceEx, определите, насколько разреженным оказывается файловое пространство, распределяемое различными версиями операционной системы Windows. Например, создайте новый файл, установите для указателя файла большое значение, задайте размер файла и исследуйте наличие свободного пространства на жестком диске при помощи функции GetDiskFreeSpace. Эту же функцию Windows можно использовать для определения того, чтобы определить, каким образом сконфигурирован диск в терминах секторов и кластеров. Определите, инициализируется ли выделенное для вновь созданного файла дисковое пространство. Решение в виде исходного текста функции FreeSpace.с доступно на Web-сайте книги. Сравните результаты, полученные для столь различных систем, как Windows NT и Windows 9x. Представляет интерес также исследование вопроса о том, как сделать файл разреженным.
3.2. Что произойдет, если длину файла задать такой, чтобы его размер превышал объем диска? Обеспечивает ли Windows изящный выход из функции в случае ее неудачного завершения?