void probe_scsi_device(long bus, long id, int unsure) { UInt32 devType; if (DoInquiry(id, bus, &devType)) { if (devType == kScsiDevTypeDirect || devType == kScsiDevTypeOptical) { add_to_cache(bus, id, 0, unsure); } else if (devType == kScsiDevTypeCDROM || devType == kScsiDevTypeWorm) { add_to_cache(bus, id, 1, unsure); } } }
VOID main( int argc, char *argv[] ) { SCSI_PASS_THROUGH_WITH_BUFFERS sptwb; DWORD accessMode, shareMode; HANDLE fileHandle; UCHAR string[25]; UCHAR szDriveNum[4]; ULONG errorCode; BOOLEAN changeSet = FALSE; ULONG i; ULONG driveNumber, sensePage, senseValues, saveAction; UCHAR changeBits[0x24]; ULONG pageLength; if (argc > 4 || (argc > 1 && argv[1][0] == '?')) { printf("Usage: %s [ModePage [Action [WhichValues]]]\n", argv[0] ); return; } shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; // default accessMode = GENERIC_WRITE | GENERIC_READ; // default printf("\nWindows NT SCSI Mode Sense and Select Utility\n"); selectDisk: printf("\n"); for (i=0;;i++) { sprintf(string, "\\\\.\\PhysicalDrive%d", i); fileHandle = CreateFile(string, accessMode, shareMode, NULL, OPEN_EXISTING, 0, NULL); if (fileHandle == INVALID_HANDLE_VALUE) { if (i == 0) { printf("Error opening PhysicalDrive0. Error: %d\n", errorCode = GetLastError()); PrintError(errorCode); return; } else { break; } } else { printf("Disk %d is a ", i); DoInquiry(&sptwb, fileHandle); printf("at SCSI ID %d\n", sptwb.spt.TargetId); CloseHandle(fileHandle); } } printf("Enter '99' to exit program\n\n"); while (TRUE) { printf("Which disk(0-%d)? ", i-1); scanf("%d", &driveNumber); if ((driveNumber >= 0) && (driveNumber < i)) { break; } else if (driveNumber == 99) { exit(0); } else { printf("There is no disk %d\n",driveNumber); } } newPage: printf("\n"); printf(" 0:Unit Attention Page\n"); printf(" 1:Error Recovery Page\n"); printf(" 2:Disconnect Page\n"); printf(" 3:Format Device Page\n"); printf(" 4:Rigid Geometry Page\n"); printf(" 5:Flexible Page\n"); printf(" 7:Verify Error Page\n"); printf(" 8:Caching Page\n"); printf(" 9:Peripheral Page\n"); printf("10:Control Page\n"); printf("11:Medium Types Page\n"); printf("12:Notch Partition Page\n"); printf("15:Data Compression Page\n"); printf("16:Device Configuration Page\n"); printf("17:Medium Partition Page\n"); printf("99:Select disk\n"); printf("\nWhich page? "); scanf("%d", &sensePage); if (sensePage > 17) { goto selectDisk; } printf("\n0:Get current values\n"); printf("1:Get default values\n"); printf("2:Get saved values\n"); printf("3:Get changable values\n"); if (sensePage == 8) { printf("4:Enable write cache\n"); printf("5:Disable write cache\n"); } printf("99:New page\n"); printf("\nWhat action? "); scanf("%d", &senseValues); if (senseValues > 5 || (sensePage != 8 && senseValues >3)) { goto newPage; } strcpy(string,"\\\\.\\PhysicalDrive"); sprintf(szDriveNum, "%d",driveNumber); strcat(string,szDriveNum); fileHandle = CreateFile(string, accessMode, shareMode, NULL, OPEN_EXISTING, 0, NULL); printf("\nMode Sense "); switch (sensePage) { case 0: printf("Unit Attention Page "); break; case 1: printf("Error Recovery Page "); break; case 2: printf("Disconnect Page "); break; case 3: printf("Format Device Page "); break; case 4: printf("Rigid Geometry Page "); break; case 5: printf("Flexible Page "); break; case 7: printf("Verify Error Page "); break; case 8: printf("Caching Page "); break; case 9: printf("Peripheral Page "); break; case 10: printf("Control Page "); break; case 11: printf("Medium Types Page "); break; case 12: printf("Notch Partition Page "); break; case 15: printf("Data Compression Page "); break; case 16: printf("Device Configuration Page "); break; case 17: printf("Medium Partition Page "); break; default: printf("Unknown Page "); break; } switch (senseValues) { case 0: printf("(current values)\n"); DoModeSense(&sptwb, fileHandle, sensePage | MODE_SENSE_CURRENT_VALUES); break; case 1: printf("(default values)\n"); DoModeSense(&sptwb, fileHandle, sensePage | MODE_SENSE_DEFAULT_VALUES); break; case 2: printf("(saved values)\n"); DoModeSense(&sptwb, fileHandle, sensePage | MODE_SENSE_SAVED_VALUES); break; case 3: printf("(changable values)\n"); DoModeSense(&sptwb, fileHandle, sensePage | MODE_SENSE_CHANGEABLE_VALUES); memcpy(changeBits, sptwb.ucDataBuf, sptwb.ucDataBuf[4+1]); pageLength = changeBits[4+1]; break; case 4: case 5: goto cachePage; default: printf("(no values)\n"); break; } goto newPage; cachePage: // // Get changable fields mask. // printf("(changable values)\n"); DoModeSense(&sptwb, fileHandle, sensePage | MODE_SENSE_CHANGEABLE_VALUES); // // Set up change mask. // memcpy(changeBits, sptwb.ucDataBuf, sptwb.ucDataBuf[4+1]); pageLength = changeBits[4+1]; // // Get current values. // printf("\nMode Sense Caching Page (old current values)\n"); DoModeSense(&sptwb, fileHandle, sensePage | MODE_SENSE_CURRENT_VALUES); // // Clear fields that can't be changed. // VerifyModePage(&sptwb.ucDataBuf[0], changeBits, pageLength); // // Set or clear write cache enable bit. // if (senseValues == 4) sptwb.ucDataBuf[4 + 2] |= 0x4; else sptwb.ucDataBuf[4+2] &= ~0x4; // // Determine whether this change should be saved. // while (TRUE) { printf("\n0:Do not save page\n"); printf("1:Save page\n"); printf("99:Select page\n"); printf("\nSave action? "); scanf("%d", &saveAction); if (saveAction == 99) { goto newPage; } if (saveAction == 0 || saveAction == 1) { break; } } DoModeSelect(&sptwb, fileHandle, saveAction, pageLength + 6); // // Get new current values. // printf("\nMode Sense Caching Page (new current values)\n"); DoModeSense(&sptwb, fileHandle, sensePage | MODE_SENSE_CURRENT_VALUES); goto newPage; }