Получение объема флеш-памяти
Получить весь объем внешней флеш-памяти можно с помощью функции расширения C_EX_GetDriveSize()
, передав в нее идентификатор слота с подключенным токеном и указатель на буфер, в который будет возвращен полученный объем памяти в Мб.
CK_ULONG ulDriveSize = 0; // Общий объем флеш-памяти printf("Get Flash memory size"); rv = pFunctionListEx->C_EX_GetDriveSize(aSlots[0], // Идентификатор слота с подключенным токеном &ulDriveSize); // Возвращаемый размер флеш-памяти в Мб if (rv != CKR_OK) printf(" -> Failed\n"); else { printf(" -> OK\n"); printf("Memory size: %d Mb\n", (int)ulDriveSize); }
Создание разделов флеш-памяти
Флеш-память Рутокен ЭЦП Flash может быть разбита на несколько независимых разделов с разными правами доступа к ним. Минимальное количество разделов – 1, максимальное – 8.
Рутокен ЭЦП Flash поддерживает следующие права доступа к разделам: для чтения и записи (ACCESS_MODE_RW
), только для чтения (ACCESS_MODE_RO
), скрытый раздел, защищенный от отображения в операционной системе, чтения, записи и любого другого типа доступа (ACCESS_MODE_HIDDEN
) и раздел, эмулирующий CD-ROM (ACCESS_MODE_CD
).
Владельцем раздела может выступать Администратор Рутокен (CKU_SO
), Пользователь Рутокен (CKU_USER
), а также локальный пользователь (с идентификатором в пределах от 0x03 до 0x1E) с предварительно заданным функцией C_EX_SetLocalPin()
PIN-кодом.
Для разметки флеш-памяти на разделы предназначена функция C_EX_FormatDrive()
. Вся информация о разделах (объем памяти, права доступа, владелец и флаги) задается в массиве структур типа CK_VOLUME_FORMAT_INFO_EXTENDED
, который затем вместе в PIN-кодом Администратора и идентификатором слота, к которому подключен Рутокен, передается в функцию C_EX_FormatDrive()
.
CK_ULONG VolumeRWSize = 0; // Размер раздела для чтения и записи CK_ULONG VolumeROSize = 0; // Размер раздела только для чтения CK_ULONG VolumeCDSize = 0; // Размер раздела CD-ROM CK_ULONG VolumeHISize = 0; // Размер раздела скрытого раздела CK_ULONG CKU_LOCAL_1 = 0x03; // Идентификатор локального пользователя CK_ULONG CKU_LOCAL_2 = 0x1E; // Идентификатор локального пользователя /* Шаблон для разметки разделов */ CK_VOLUME_FORMAT_INFO_EXTENDED InitParams[] = { { VolumeRWSize, ACCESS_MODE_RW, CKU_USER, 0 }, { VolumeROSize, ACCESS_MODE_RO, CKU_SO, 0 }, { VolumeHISize, ACCESS_MODE_HIDDEN, CKU_LOCAL_1, 0 }, { VolumeCDSize, ACCESS_MODE_CD, CKU_LOCAL_2, 0 } }; ... InitParams[0].ulVolumeSize = ulDriveSize / 2; InitParams[1].ulVolumeSize = ulDriveSize / 4; InitParams[2].ulVolumeSize = ulDriveSize / 8; InitParams[3].ulVolumeSize = ulDriveSize - (ulDriveSize / 2) - (ulDriveSize / 4) - (ulDriveSize / 8); printf("\nFormatting flash memory"); rv = pFunctionListEx->C_EX_FormatDrive( aSlots[0], // Идентификатор слота с подключенным токеном CKU_SO, // Форматирование выполняется только с правами Администратора SO_PIN, // Текущий PIN-код Администратора sizeof(SO_PIN), // Длина PIN-кода Администратора InitParams, // Массив с информацией о разделах arraysize(InitParams)); // Размер массива if (rv != CKR_OK) printf(" -> Failed\n"); else printf(" -> OK\n");
Получение информации о разделах флеш-памяти
Получить информацию о существующих на флеш-памяти разделах можно с помощью функции C_EX_GetVolumesInfo()
, передав в нее идентификатор слота, к которому подключен токен, указатель на буфер и его размер, куда будет возвращен массив структур типа CK_VOLUME_INFO_EXTENDED
с информацией о разделах (идентификатор раздела, его размер, права доступа, владелец и флаги). Размер буфера можно определить, вызвав C_EX_GetVolumesInfo()
с пустым указателем на буфер.
CK_VOLUME_INFO_EXTENDED_PTR pVolumesInfo = NULL_PTR; // Указатель на массив структур с информацией о разделах CK_ULONG ulVolumesInfoCount = 0; // Размер массива с информацией о разделах printf("\nGetting volumes info"); rv = pFunctionListEx->C_EX_GetVolumesInfo( aSlots[0], // Идентификатор слота с подключенным токеном NULL_PTR, // Указатель на массив с возвращаемой информацией о разделах &ulVolumesInfoCount);// Размер массива pVolumesInfo = (CK_VOLUME_INFO_EXTENDED*)malloc(ulVolumesInfoCount * sizeof(CK_VOLUME_INFO_EXTENDED)); memset(pVolumesInfo, 0, (ulVolumesInfoCount * sizeof(CK_ULONG))); rv = pFunctionListEx->C_EX_GetVolumesInfo(aSlots[0], // Идентификатор слота с подключенным токеном pVolumesInfo, // Указатель на массив с возвращаемой информацией о разделах &ulVolumesInfoCount); // Размер массива if (rv != CKR_OK) { printf(" -> Failed\n"); } else { printf(" -> OK\n"); for (i = 0; i < (int)ulVolumesInfoCount; i++) { printf("\nPrinting volume %1.2d info:\n", (int)i+1); printf(" Volume id: %2.2d \n", pVolumesInfo[i].idVolume); // Идентификатор раздела printf(" Volume size: %d Mb \n", pVolumesInfo[i].ulVolumeSize); // Объем раздела printf(" Access mode: %2.2d \n", pVolumesInfo[i].accessMode); // Права доступа к разделу printf(" Volume owner: %2.2d \n", pVolumesInfo[i].volumeOwner); // Владелец раздела printf(" Flags: 0x%8.8X \n", pVolumesInfo[i].flags); // Флаги раздела } }
Изменение атрибутов разделов флеш-памяти
Работа с защищенными разделами (с правами доступа только для чтения, скрытым и CD-ROM разделам) сводится к тому, что владелец раздела на время работы с разделом меняет к нему права доступа. Доступно два способа изменения атрибутов раздела: временное и постоянное. Временное изменение меняет права доступа до первого отключения устройства из USB-порта, после чего права доступа сбрасываются на прежние. Постоянное изменение атрибутов доступа действует вплоть до следующего изменения атрибутов.
Для обоих способов изменения атрибутов используется одна функция C_EX_ChangeVolumeAttributes()
, в которую передается идентификатор слота с подключенным токеном, владелец раздела и его PIN-код, а также новые права доступа к разделу и флаг временности/постоянности изменения.
printf("\nChanging volume attributes"); rv = pFunctionListEx->C_EX_ChangeVolumeAttributes(aSlots[0], // Идентификатор слота с подключенным токеном CKU_SO, // Владелец раздела SO_PIN, // PIN-код владельца раздела sizeof(SO_PIN), // Длина PIN-кода владельца раздела VolumeRO, // Идентификатор раздела ACCESS_MODE_RW, // Новые права доступа к разделу CK_TRUE); // CK_TRUE - постоянное изменение атрибутов, CK_FALSE - временное изменение атрибутов if (rv != CKR_OK) printf(" -> Failed\n"); else printf(" -> OK\n");