Changeset 133 for trunk/src/helpers/dosh.c
- Timestamp:
- Jan 26, 2002, 4:59:23 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/dosh.c
r132 r133 291 291 292 292 /* 293 *@@ Allocate:293 *@@ doshMalloc: 294 294 * wrapper around malloc() which automatically 295 295 * sets ERROR_NOT_ENOUGH_MEMORY. … … 457 457 UCHAR ucNonRemoveable; 458 458 459 parms.drive = (UCHAR)(ulLogicalDrive-1); 460 arc = doshDevIOCtl((HFILE)-1, 461 IOCTL_DISK, // 0x08 462 DSK_BLOCKREMOVABLE, // 0x20 463 &parms, sizeof(parms), 464 &ucNonRemoveable, sizeof(ucNonRemoveable)); 465 466 if (arc == NO_ERROR) 459 parms.drive = (UCHAR)(ulLogicalDrive - 1); 460 if (!(arc = doshDevIOCtl((HFILE)-1, 461 IOCTL_DISK, // 0x08 462 DSK_BLOCKREMOVABLE, // 0x20 463 &parms, sizeof(parms), 464 &ucNonRemoveable, sizeof(ucNonRemoveable)))) 467 465 *pfFixed = (BOOL)ucNonRemoveable; 468 466 } … … 504 502 * 505 503 * This returns the DOS error code of DosDevIOCtl. 504 * This will be: 505 * 506 * -- NO_ERROR for all local disks; 507 * 508 * -- ERROR_NOT_SUPPORTED (50) for network drives. 506 509 * 507 510 *@@added V0.9.0 [umoeller] … … 552 555 553 556 /* 554 *@@ dosh IsCDROM:557 *@@ doshQueryRemoveableType: 555 558 * tests the specified BIOSPARAMETERBLOCK 556 * for whether it represents a CD-ROM drive. 559 * for whether it represents a CD-ROM or 560 * some other removeable drive type. 561 * 562 * Returns one of: 563 * 564 * -- 0 565 * 566 * -- DRVTYPE_CDROM 567 * 568 * Call this only if doshIsFixedDisk 569 * returned FALSE. 557 570 * 558 571 * The BIOSPARAMETERBLOCK must be filled 559 572 * first using doshQueryDiskParams. 560 573 * 561 *@@added V0.9.13 (2001-06-14) [umoeller] 562 */ 563 564 BOOL doshIsCDROM(PBIOSPARAMETERBLOCK pdp) 565 { 566 return ( (pdp) 567 && (pdp->bDeviceType == 7) // "other" 574 *@@added V0.9.16 (2002-01-13) [umoeller] 575 */ 576 577 BYTE doshQueryRemoveableType(PBIOSPARAMETERBLOCK pdp) 578 { 579 if (pdp) 580 { 581 if ( (pdp->bDeviceType == 7) // "other" 568 582 && (pdp->usBytesPerSector == 2048) 569 583 && (pdp->usSectorsPerTrack == (USHORT)-1) 570 ); 584 ) 585 return DRVTYPE_CDROM; 586 else if (pdp->fsDeviceAttr & DEVATTR_PARTITIONALREMOVEABLE) // 0x08 587 return DRVTYPE_PARTITIONABLEREMOVEABLE; 588 else if (pdp->bDeviceType == 6) // tape 589 return DRVTYPE_TAPE; 590 } 591 592 return (0); 571 593 } 572 594 … … 578 600 * Better call this only if you're sure that 579 601 * ulLogicalDrive is a CD-ROM drive. Use 580 * dosh IsCDROMto check.602 * doshQueryRemoveableType to check. 581 603 * 582 604 *@@added V0.9.14 (2001-08-01) [umoeller] … … 798 820 * single (capital) character, which is useful for 799 821 * constructing file names using sprintf and such. 822 * 823 *@@changed V0.9.16 (2002-01-13) [umoeller]: optimized 800 824 */ 801 825 802 826 CHAR doshQueryBootDrive(VOID) 803 827 { 804 ULONG ulBootDrive; 805 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, 806 &ulBootDrive, 807 sizeof(ulBootDrive)); 808 return (ulBootDrive + 'A' - 1); 828 // this can never change, so query this only once 829 // V0.9.16 (2002-01-13) [umoeller] 830 static CHAR cBootDrive = '\0'; 831 832 if (!cBootDrive) 833 { 834 ULONG ulBootDrive; 835 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, 836 &ulBootDrive, 837 sizeof(ulBootDrive)); 838 cBootDrive = (CHAR)ulBootDrive + 'A' - 1; 839 } 840 841 return (cBootDrive); 842 } 843 844 /* 845 *@@ doshQueryMedia: 846 * determines whether the given drive currently 847 * has media inserted. 848 * 849 * Call this only for non-fixed (removable) disks. 850 * Use doshIsFixedDisk to find out. 851 * 852 *@@added V0.9.16 (2002-01-13) [umoeller] 853 */ 854 855 APIRET doshQueryMedia(ULONG ulLogicalDrive, 856 BOOL fCDROM, 857 ULONG fl) // in: DRVFL_* flags 858 { 859 APIRET arc; 860 861 HFILE hf = NULLHANDLE; 862 ULONG dummy; 863 864 CHAR szDrive[3] = "C:"; 865 szDrive[0] = 'A' + ulLogicalDrive - 1; 866 867 arc = DosOpen(szDrive, // "C:", "D:", ... 868 &hf, 869 &dummy, 870 0, 871 FILE_NORMAL, 872 OPEN_ACTION_FAIL_IF_NEW 873 | OPEN_ACTION_OPEN_IF_EXISTS, 874 OPEN_FLAGS_DASD 875 | OPEN_FLAGS_FAIL_ON_ERROR 876 | OPEN_FLAGS_NOINHERIT // V0.9.6 (2000-11-25) [pr] 877 // | OPEN_ACCESS_READONLY // V0.9.13 (2001-06-14) [umoeller] 878 | OPEN_SHARE_DENYNONE, 879 NULL); 880 881 // this still returns NO_ERROR for audio CDs in a 882 // CD-ROM drive... 883 // however, the WPS then attempts to read in the 884 // root directory for audio CDs, which produces 885 // a "sector not found" error box... 886 887 if ( (!arc) 888 && (hf) 889 && (fCDROM) 890 ) 891 { 892 BOOL fAudio; 893 if ( (!(arc = doshHasAudioCD(ulLogicalDrive, 894 hf, 895 ((fl & DRVFL_MIXEDMODECD) != 0), 896 &fAudio))) 897 && (fAudio) 898 ) 899 arc = ERROR_AUDIO_CD_ROM; // special private error code (10000) 900 } 901 902 if (hf) 903 DosClose(hf); 904 905 return (arc); 809 906 } 810 907 … … 818 915 * and can be any combination of: 819 916 * 820 * -- ASSERTFL_MIXEDMODECD: whether to allow917 * -- DRVFL_MIXEDMODECD: whether to allow 821 918 * mixed-mode CD-ROMs. See error codes below. 822 919 * … … 835 932 * media inserted. 836 933 * 837 * If ASSERTFL_MIXEDMODECD was specified, ERROR_AUDIO_CD_ROM934 * If DRVFL_MIXEDMODECD was specified, ERROR_AUDIO_CD_ROM 838 935 * is returned _only_ if _no_ data tracks are 839 936 * present on a CD-ROM. Since OS/2 is not very … … 841 938 * be desireable. 842 939 * 843 * If ASSERTFL_MIXEDMODECD was not set, ERROR_AUDIO_CD_ROM940 * If DRVFL_MIXEDMODECD was not set, ERROR_AUDIO_CD_ROM 844 941 * will be returned already if _one_ audio track is present. 845 942 * … … 855 952 856 953 APIRET doshAssertDrive(ULONG ulLogicalDrive, // in: 1 for A:, 2 for B:, 3 for C:, ... 857 ULONG fl) // in: ASSERTFL_* flags954 ULONG fl) // in: DRVFL_* flags 858 955 { 859 956 APIRET arc = NO_ERROR; … … 881 978 882 979 if ( (!arc) 883 && ( doshIsCDROM(&bpb))980 && (DRVTYPE_CDROM == doshQueryRemoveableType(&bpb)) 884 981 ) 885 982 { … … 890 987 891 988 if (!arc) 892 { 893 HFILE hfDrive = NULLHANDLE; 894 895 ULONG ulTemp = 0; 896 CHAR szDrive[3] = "C:"; 897 szDrive[0] = 'A' + ulLogicalDrive - 1; 898 899 arc = DosOpen(szDrive, // "C:", "D:", ... 900 &hfDrive, 901 &ulTemp, 902 0, 903 FILE_NORMAL, 904 OPEN_ACTION_FAIL_IF_NEW 905 | OPEN_ACTION_OPEN_IF_EXISTS, 906 OPEN_FLAGS_DASD 907 | OPEN_FLAGS_FAIL_ON_ERROR 908 | OPEN_FLAGS_NOINHERIT // V0.9.6 (2000-11-25) [pr] 909 // | OPEN_ACCESS_READONLY // V0.9.13 (2001-06-14) [umoeller] 910 | OPEN_SHARE_DENYNONE, 911 NULL); 912 913 // _Pmpf((" DosOpen(OPEN_FLAGS_DASD) returned %d", arc)); 914 915 // this still returns NO_ERROR for audio CDs in a 916 // CD-ROM drive... 917 // however, the WPS then attempts to read in the 918 // root directory for audio CDs, which produces 919 // a "sector not found" error box... 920 921 if ( (!arc) 922 && (hfDrive) 923 && (fCDROM) 924 ) 925 { 926 BOOL fAudio; 927 if ( (!(arc = doshHasAudioCD(ulLogicalDrive, 928 hfDrive, 929 ((fl & ASSERTFL_MIXEDMODECD) != 0), 930 &fAudio))) 931 && (fAudio) 932 ) 933 arc = ERROR_AUDIO_CD_ROM; // special private error code (10000) 934 } 935 936 if (hfDrive) 937 DosClose(hfDrive); 938 } 989 arc = doshQueryMedia(ulLogicalDrive, 990 fCDROM, 991 fl); 939 992 940 993 switch (arc) … … 972 1025 break; 973 1026 } 1027 1028 return (arc); 1029 } 1030 1031 /* 1032 *@@ doshGetDriveInfo: 1033 * fills the given XDISKINFO buffer with 1034 * information about the given logical drive. 1035 * 1036 * This function will not provoke "Drive not 1037 * ready" popups, hopefully. Tested with the 1038 * following drive types: 1039 * 1040 * -- all kinds of local partitions (FAT, 1041 * FAT32, HPFS, JFS) 1042 * 1043 * -- remote NetBIOS drives added via "net use" 1044 * 1045 * -- CD-ROM drives; one DVD drive and one 1046 * CD writer, even if no media is present 1047 * 1048 * fl can be any combination of the following: 1049 * 1050 * -- DRVFL_MIXEDMODECD: see doshAssertDrive. 1051 * 1052 * -- DRVFL_TOUCHFLOPPIES: drive A: and B: should 1053 * be touched for media checks (click, click); 1054 * otherwise they will be left alone and 1055 * default values will be returned. 1056 * 1057 * This should return only one of the following: 1058 * 1059 * -- ERROR_INVALID_DRIVE: drive letter is invalid 1060 * 1061 * -- ERROR_DRIVE_LOCKED 1062 * 1063 * -- NO_ERROR: disk info was filled, but not 1064 * necessarily all info was available (e.g. 1065 * if no media was present in CD-ROM drive). 1066 * 1067 *@@added V0.9.16 (2002-01-13) [umoeller] 1068 */ 1069 1070 APIRET doshGetDriveInfo(ULONG ulLogicalDrive, 1071 ULONG fl, // in: DRVFL_* flags 1072 PXDISKINFO pdi) 1073 { 1074 APIRET arc = NO_ERROR; 1075 1076 HFILE hf; 1077 ULONG dummy; 1078 BOOL fCheck = TRUE; 1079 1080 memset(pdi, 0, sizeof(XDISKINFO)); 1081 1082 pdi->cDriveLetter = 'A' + ulLogicalDrive - 1; 1083 pdi->cLogicalDrive = ulLogicalDrive; 1084 1085 pdi->bType = DRVTYPE_UNKNOWN; 1086 pdi->fPresent = TRUE; // for now 1087 1088 if ( (ulLogicalDrive == 1) 1089 || (ulLogicalDrive == 2) 1090 ) 1091 { 1092 // drive A: and B: are special cases, 1093 // we don't even want to touch them (click, click) 1094 pdi->bType = DRVTYPE_FLOPPY; 1095 1096 if (0 == (fl & DRVFL_TOUCHFLOPPIES)) 1097 { 1098 fCheck = FALSE; 1099 // these support EAs too 1100 pdi->flDevice = DFL_MEDIA_PRESENT | DFL_SUPPORTS_EAS; 1101 strcpy(pdi->szFileSystem, "FAT"); 1102 pdi->bFileSystem = FSYS_FAT; 1103 } 1104 } 1105 1106 if (fCheck) 1107 { 1108 // any other drive: 1109 // check if it's removeable first 1110 BOOL fFixed = FALSE; 1111 arc = doshIsFixedDisk(ulLogicalDrive, 1112 &fFixed); 1113 1114 if (arc == ERROR_INVALID_DRIVE) 1115 // drive letter doesn't exist at all: 1116 pdi->fPresent = FALSE; 1117 // return this APIRET 1118 else 1119 { 1120 BOOL fCheckFS = FALSE; 1121 BOOL fCheckLongnames = FALSE; 1122 1123 if (fFixed) 1124 // fixed drive: 1125 pdi->flDevice |= DFL_FIXED | DFL_MEDIA_PRESENT; 1126 1127 if (!(arc = doshQueryDiskParams(ulLogicalDrive, 1128 &pdi->bpb))) 1129 { 1130 if (!fFixed) 1131 { 1132 // removeable: 1133 BYTE bTemp; 1134 if (bTemp = doshQueryRemoveableType(&pdi->bpb)) 1135 { 1136 // DRVTYPE_TAPE or DRVTYPE_CDROM 1137 pdi->bType = bTemp; 1138 1139 if (bTemp == DRVTYPE_PARTITIONABLEREMOVEABLE) 1140 pdi->flDevice |= DFL_FIXED 1141 | DFL_PARTITIONABLEREMOVEABLE; 1142 } 1143 1144 // before checking the drive, try if we have media 1145 if (!(arc = doshQueryMedia(ulLogicalDrive, 1146 (pdi->bType == DRVTYPE_CDROM), 1147 fl))) 1148 { 1149 pdi->flDevice |= DFL_MEDIA_PRESENT; 1150 fCheckFS = TRUE; 1151 fCheckLongnames = TRUE; 1152 } 1153 else if (arc == ERROR_AUDIO_CD_ROM) 1154 { 1155 pdi->flDevice |= DFL_AUDIO_CD; 1156 // do not check longnames and file-system 1157 } 1158 1159 arc = NO_ERROR; 1160 } 1161 else 1162 { 1163 pdi->bType = DRVTYPE_HARDDISK; 1164 fCheckFS = TRUE; 1165 } 1166 } 1167 else if (arc == ERROR_NOT_SUPPORTED) // 50 1168 { 1169 // we get this for remote drives added 1170 // via "net use", so set these flags 1171 pdi->bType = DRVTYPE_LAN; 1172 pdi->bFileSystem = FSYS_REMOTE; 1173 pdi->flDevice |= DFL_REMOTE | DFL_MEDIA_PRESENT; 1174 // but still check what file-system we 1175 // have and whether longnames are supported 1176 fCheckFS = TRUE; 1177 fCheckLongnames = TRUE; 1178 } 1179 1180 if (fCheckFS) 1181 { 1182 // TRUE only for local fixed disks or 1183 // remote drives or if media was present above 1184 if (!(arc = doshQueryDiskFSType(ulLogicalDrive, 1185 pdi->szFileSystem, 1186 sizeof(pdi->szFileSystem)))) 1187 { 1188 if (!stricmp(pdi->szFileSystem, "FAT")) 1189 { 1190 pdi->bFileSystem = FSYS_FAT; 1191 pdi->flDevice |= DFL_SUPPORTS_EAS; 1192 fCheckLongnames = FALSE; 1193 } 1194 else if ( (!stricmp(pdi->szFileSystem, "HPFS")) 1195 || (!stricmp(pdi->szFileSystem, "JFS")) 1196 ) 1197 { 1198 pdi->bFileSystem = FSYS_HPFS_JFS; 1199 pdi->flDevice |= DFL_SUPPORTS_EAS | DFL_SUPPORTS_LONGNAMES; 1200 fCheckLongnames = FALSE; 1201 } 1202 else if (!stricmp(pdi->szFileSystem, "CDFS")) 1203 pdi->bFileSystem = FSYS_CDFS; 1204 else if (!stricmp(pdi->szFileSystem, "FAT32")) 1205 { 1206 pdi->bFileSystem = FSYS_FAT32; 1207 pdi->flDevice |= DFL_SUPPORTS_LONGNAMES; 1208 // @@todo check EA support 1209 fCheckLongnames = FALSE; 1210 } 1211 else if (!stricmp(pdi->szFileSystem, "RAMFS")) 1212 { 1213 pdi->bFileSystem = FSYS_RAMFS; 1214 pdi->flDevice |= DFL_SUPPORTS_EAS | DFL_SUPPORTS_LONGNAMES; 1215 fCheckLongnames = FALSE; 1216 } 1217 } 1218 // else if this failed, we had an error popup!! 1219 // shouldn't happen!! 1220 } 1221 1222 if (fCheckLongnames) 1223 { 1224 CHAR szTemp[30] = "?:\\long.name.file"; 1225 szTemp[0] = ulLogicalDrive + 'A' - 1; 1226 if (!(arc = DosOpen(szTemp, 1227 &hf, 1228 &dummy, 1229 0, 1230 0, 1231 FILE_READONLY, 1232 OPEN_SHARE_DENYNONE | OPEN_FLAGS_NOINHERIT, 1233 0))) 1234 { 1235 DosClose(hf); 1236 } 1237 1238 switch (arc) 1239 { 1240 case NO_ERROR: 1241 case ERROR_OPEN_FAILED: 1242 pdi->flDevice |= DFL_SUPPORTS_LONGNAMES; 1243 1244 // otherwise we get ERROR_INVALID_NAME 1245 // default: 1246 // printf(" drive %d returned %d\n", ulLogicalDrive, arc); 1247 } 1248 1249 arc = NO_ERROR; 1250 } 1251 } 1252 } 1253 1254 if (doshQueryBootDrive() == pdi->cDriveLetter) 1255 pdi->flDevice |= DFL_BOOTDRIVE; 974 1256 975 1257 return (arc); … … 2522 2804 * Example: Assuming TEMP is set to C:\TEMP, 2523 2805 + 2524 + dos CreateTempFileName(szBuffer,2525 + NULL, // use $(TEMP)2526 + "pre", // prefix2527 + "tmp") // extension2806 + doshCreateTempFileName(szBuffer, 2807 + NULL, // use $(TEMP) 2808 + "pre", // prefix 2809 + "tmp") // extension 2528 2810 + 2529 2811 * would produce something like "C:\TEMP\pre07FG2.tmp". … … 3667 3949 } 3668 3950 3669 3951 /* ****************************************************************** 3952 * 3953 * Testcase 3954 * 3955 ********************************************************************/ 3956 3957 #ifdef BUILD_MAIN 3958 3959 int main (int argc, char *argv[]) 3960 { 3961 ULONG ul; 3962 3963 printf(" type fs remot fixed parrm bootd media audio eas longn\n"); 3964 3965 for (ul = 1; 3966 ul <= 26; 3967 ul++) 3968 { 3969 XDISKINFO xdi; 3970 APIRET arc = doshGetDriveInfo(ul, 3971 0, // DRVFL_TOUCHFLOPPIES, 3972 &xdi); 3973 PCSZ pcsz = "unknown"; 3974 3975 printf(" %c: ", xdi.cDriveLetter, ul); 3976 3977 if (!xdi.fPresent) 3978 printf("not present\n"); 3979 else 3980 { 3981 if (arc) 3982 printf("error %4d\n", arc); 3983 else 3984 { 3985 ULONG aulFlags[] = 3986 { 3987 DFL_REMOTE, 3988 DFL_FIXED, 3989 DFL_PARTITIONABLEREMOVEABLE, 3990 DFL_BOOTDRIVE, 3991 0, 3992 DFL_MEDIA_PRESENT, 3993 DFL_AUDIO_CD, 3994 DFL_SUPPORTS_EAS, 3995 DFL_SUPPORTS_LONGNAMES 3996 }; 3997 ULONG ul2; 3998 3999 switch (xdi.bType) 4000 { 4001 case DRVTYPE_HARDDISK: pcsz = "HARDDISK"; break; 4002 case DRVTYPE_FLOPPY: pcsz = "FLOPPY "; break; 4003 case DRVTYPE_TAPE: pcsz = "TAPE "; break; 4004 case DRVTYPE_VDISK: pcsz = "VDISK "; break; 4005 case DRVTYPE_CDROM: pcsz = "CDROM "; break; 4006 case DRVTYPE_LAN: pcsz = "LAN "; break; 4007 case DRVTYPE_PARTITIONABLEREMOVEABLE: 4008 pcsz = "PARTREMV"; break; 4009 } 4010 4011 printf("%s ", pcsz); 4012 4013 printf("%8s ", xdi.szFileSystem); // , xdi.bFileSystem); 4014 4015 for (ul2 = 0; 4016 ul2 < ARRAYITEMCOUNT(aulFlags); 4017 ul2++) 4018 { 4019 if (xdi.flDevice & aulFlags[ul2]) 4020 printf(" X "); 4021 else 4022 printf(" - "); 4023 } 4024 printf("\n"); 4025 } 4026 } 4027 } 4028 } 4029 4030 #endif
Note:
See TracChangeset
for help on using the changeset viewer.