BOOL FileNameComplete(Object *obj, BOOL backwards, struct InstData *data) { BOOL edited = FALSE; ENTER(); if(data->FNCBuffer != NULL) { if(data->FileEntries == 1) { DisplayBeep(NULL); } else { if(backwards) { if(--data->FileNumber < 0) data->FileNumber = data->FileEntries-1; } else { if(++data->FileNumber >= data->FileEntries) data->FileNumber = 0; } } InsertFileName(data->FileNameStart, data); edited = TRUE; } else { LONG pos = DoMethod(obj, MUIM_BetterString_FileNameStart, data->Contents, data->BufferPos); switch(pos) { case MUIR_BetterString_FileNameStart_Volume: { struct DosList *dl; STRPTR volumeName = NULL; char tmpBuffer[256]; UWORD cut; pos = VolumeStart(data->Contents, data->BufferPos); if((cut = data->BufferPos-pos) != 0) { dl = LockDosList(LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS); while((dl = NextDosEntry(dl, LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS)) != NULL) { #ifdef __AROS__ strlcpy(tmpBuffer, dl->dol_Ext.dol_AROS.dol_DevName, sizeof tmpBuffer); #else // dol_Name is a BSTR, we have to convert it to a regular C string char *bstr = BADDR(dl->dol_Name); // a BSTR cannot exceed 255 characters, hence the buffer size of 256 is enough in any case strlcpy(tmpBuffer, &bstr[1], (unsigned char)bstr[0]); #endif if(Strnicmp(tmpBuffer, data->Contents+pos, cut) == 0) { volumeName = tmpBuffer; break; } } if(volumeName != NULL) { if(OverwriteA(volumeName, pos, cut, strlen(volumeName)+1, data)) data->Contents[data->BufferPos-1] = ':'; edited = TRUE; } UnLockDosList(LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS); } } break; default: { struct FNCData *fncbuffer; struct FNCData *fncframe; struct ExAllControl *control; BPTR dirlock; char pattern[42]; UWORD namestart = data->BufferPos; char oldletter = '\0'; BOOL filename = TRUE; while(filename) { switch(*(data->Contents+namestart-1)) { case '/': case ':': filename = FALSE; break; default: namestart--; break; } } if((data->BufferPos-namestart) < 32) { strlcpy(pattern, data->Contents+namestart, sizeof(pattern)); strlcat(pattern, "~(#?.info)", sizeof(pattern)); oldletter = data->Contents[namestart]; data->Contents[namestart] = '\0'; if((fncbuffer = (struct FNCData *)SharedPoolAlloc(4100)) != NULL) { fncbuffer->next = NULL; if((control = (struct ExAllControl *)AllocDosObject(DOS_EXALLCONTROL, NULL))) { char tokenized[sizeof(pattern) * 2 + 2]; if(ParsePatternNoCase(pattern, tokenized, sizeof(tokenized)) != -1) control->eac_MatchString = tokenized; if((dirlock = Lock(data->Contents+pos, ACCESS_READ))) { UWORD entries = 0; fncframe = fncbuffer; while(fncframe && ExAll(dirlock, &fncframe->buffer, 4096, ED_TYPE, control)) { entries += control->eac_Entries; if((fncframe->next = (struct FNCData *)SharedPoolAlloc(4100))) fncframe->next->next = NULL; fncframe = fncframe->next; } control->eac_Entries += entries; data->FileNumber = backwards ? control->eac_Entries-1 : 0; data->FileEntries = control->eac_Entries; data->FileNameStart = namestart; data->FNCBuffer = fncbuffer; if(control->eac_Entries) { data->Contents[namestart] = oldletter; InsertFileName(namestart, data); edited = TRUE; } UnLock(dirlock); } else { SharedPoolFree(fncbuffer); } FreeDosObject(DOS_EXALLCONTROL, (APTR)control); } } } if(edited == FALSE) data->Contents[namestart] = oldletter; } break; } } RETURN(edited); return edited; }
// ------------------------------------------------------ // Fill the list with the content of the relevant directory void Read_SMPT(void) { int i; lt_items[Scopish] = 0; list_counter[Scopish] = 0; #if defined(__WIN32__) struct _finddata_t c_file; #endif long hFile; nbr_dirs = 0; switch(Scopish) { case SCOPE_ZONE_MOD_DIR: cur_dir = Dir_Mods; break; case SCOPE_ZONE_INSTR_DIR: cur_dir = Dir_Instrs; break; case SCOPE_ZONE_PRESET_DIR: cur_dir = Dir_Presets; break; case SCOPE_ZONE_REVERB_DIR: cur_dir = Dir_Reverbs; break; case SCOPE_ZONE_PATTERN_DIR: cur_dir = Dir_Patterns; break; case SCOPE_ZONE_SAMPLE_DIR: cur_dir = Dir_Samples; break; case SCOPE_ZONE_MIDICFG_DIR: cur_dir = Dir_MidiCfg; break; } CHDIR(cur_dir); // Find first .c file in current directory strcpy(Dir_Act, cur_dir); #if defined(__WIN32__) strcat(Dir_Act, "\\*.*"); if((hFile = _findfirst(Dir_Act, &c_file)) == -1L) { Add_Entry("No files in current directory.", 0); } else { // The first directory if(c_file.attrib & _A_SUBDIR) { if(strcmp(c_file.name, ".") && strcmp(c_file.name, "..")) { nbr_dirs++; Add_Entry(c_file.name, _A_SUBDIR); } } // Find the rest of the directories while(_findnext(hFile, &c_file) == 0) { if(c_file.attrib & _A_SUBDIR) { if(strcmp(c_file.name, ".") && strcmp(c_file.name, "..")) { nbr_dirs++; Add_Entry(c_file.name, _A_SUBDIR); } } } // End dir _findclose(hFile); if((hFile = _findfirst(Dir_Act, &c_file)) != -1L) { // The first file if(!(c_file.attrib & _A_SUBDIR)) { Add_Entry(c_file.name, 0); } // Find the rest of the files while(_findnext(hFile, &c_file) == 0) { if(!(c_file.attrib & _A_SUBDIR)) { Add_Entry(c_file.name, 0); } } // while _findclose(hFile); if(sort_files) { qsort(&SMPT_LIST[0], list_counter[Scopish], sizeof(FILEENTRY), &FileComp_Files); //Insert_List_Separators(); } //else { Insert_Entry("", _A_SEP, 0); } Insert_Entry("..", _A_SUBDIR, 0); Insert_Entry(".", _A_SUBDIR, 0); } } // Add the available drives to the bottom of the list char *Ptr_Drives; GetLogicalDriveStrings(1024, List_Drives); Ptr_Drives = List_Drives; i = 0; if(Ptr_Drives[0]) Add_Entry("", _A_SEP); while(Ptr_Drives[0]) { Add_Entry(Ptr_Drives, _A_SUBDIR); Ptr_Drives += strlen(Ptr_Drives) + 1; } #elif defined(__AMIGAOS4__) || defined(__AROS__) #if defined(__AMIGAOS4__) #define LockDosList(f) IDOS->LockDosList(f) #define NextDosEntry(d,f) IDOS->NextDosEntry(d, f) #define CopyStringBSTRToC(bin,sout,len) IDOS->CopyStringBSTRToC(bin, sout, len) #define UnLockDosList(f) IDOS->UnLockDosList(f) #endif if (!strcmp(Dir_Act, "/")) { // Only display volumes struct DosList *dl; const uint32 flags = LDF_VOLUMES | LDF_READ; char BString[1024]; dl = LockDosList(flags); while ((dl = NextDosEntry(dl, flags)) != NULL) { // Convert it first CopyStringBSTRToC(dl->dol_Name, BString, sizeof(BString)); Add_Entry(BString, _A_SUBDIR); } UnLockDosList(flags); } else { DIR *dirp; struct dirent *dp; dirp = opendir(Dir_Act); if (dirp) { // Add the directories first while ((dp = readdir(dirp)) != NULL) { if(dp->d_type == DT_DIR) { nbr_dirs++; Add_Entry(dp->d_name, _A_SUBDIR); } } closedir(dirp); } dirp = opendir(Dir_Act); if (dirp) { // Then add the files while ((dp = readdir(dirp)) != NULL) { if(dp->d_type != DT_DIR) { Add_Entry(dp->d_name, 0); } } closedir(dirp); } if(sort_files) { qsort(&SMPT_LIST[0], list_counter[Scopish], sizeof(FILEENTRY), &FileComp_Files); //Insert_List_Separators(); } //else { Insert_Entry("", _A_SEP, 0); } // Insert parent directory at the top Insert_Entry("/", _A_SUBDIR, 0); } #else // Enum them nftw(Dir_Act, &list_file, FTW_PHYS, 0); if(sort_files) { qsort(&SMPT_LIST[0], list_counter[Scopish], sizeof(FILEENTRY), &FileComp_Files); //Insert_List_Separators(); } //else { Insert_Entry("", _A_SEP, 0); } // Always insert them at the top of the list Insert_Entry("../", _A_SUBDIR, 0); Insert_Entry("./", _A_SUBDIR, 0); #endif // Insert a separator between files and directories if(nbr_dirs) { for(i = list_counter[Scopish] - 1; i >= 0; i--) { if(SMPT_LIST[i].Type == _A_FILE) { Insert_Entry("", _A_SEP, i + 1); break; } } } }
struct DiskIO *DIO_Setup(CONST_STRPTR name, const struct TagItem *tags) { DEBUGF("DIO_Setup('%s', %#p)\n", name, tags); if (name == NULL || name[0] == '\0' || name[0] == ':') { DEBUGF("DIO_Setup: No valid name argument specified.\n"); return NULL; } struct DiskIO *dio; struct TagItem *tstate; const struct TagItem *tag; #ifndef DISABLE_DOSTYPE_CHECK ULONG check_dostype = 0; ULONG dostype_mask = ~0; #endif struct DosList *dol; struct DeviceNode *dn = NULL; struct FileSysStartupMsg *fssm = NULL; struct DosEnvec *de = NULL; struct MsgPort *mp = NULL; struct IOExtTD *iotd = NULL; char devname[256]; struct NSDeviceQueryResult nsdqr; int error = DIO_ERROR_UNSPECIFIED; int *error_storage; dio = AllocMem(sizeof(*dio), MEMF_PUBLIC|MEMF_CLEAR); if (dio == NULL) { error = DIO_ERROR_NOMEM; goto cleanup; } tstate = (struct TagItem *)tags; while ((tag = NextTagItem(&tstate)) != NULL) { switch (tag->ti_Tag) { #ifndef DISABLE_BLOCK_CACHE case DIOS_Cache: dio->no_cache = !tag->ti_Data; break; case DIOS_WriteCache: dio->no_write_cache = !tag->ti_Data; break; #endif case DIOS_Inhibit: dio->inhibit = !!tag->ti_Data; break; #ifndef DISABLE_DOSTYPE_CHECK case DIOS_DOSType: check_dostype = tag->ti_Data; break; case DIOS_DOSTypeMask: dostype_mask = tag->ti_Data; break; #endif case DIOS_ReadOnly: dio->read_only = !!tag->ti_Data; break; } } /* Remove possible colon from name and anything else that might follow it */ SplitName(name, ':', dio->devname, 0, sizeof(dio->devname)); /* Find device node */ dol = LockDosList(LDF_DEVICES|LDF_READ); if (dol != NULL) { dn = (struct DeviceNode *)FindDosEntry(dol, dio->devname, LDF_DEVICES|LDF_READ); UnLockDosList(LDF_DEVICES|LDF_READ); } if (dn == NULL) { error = DIO_ERROR_GETFSD; goto cleanup; } /* Add back trailing colon for Inhibit() */ strlcat((char *)dio->devname, ":", sizeof(dio->devname)); /* Check that device node has the necessary data */ if ((fssm = BADDR(dn->dn_Startup)) == NULL || (de = BADDR(fssm->fssm_Environ)) == NULL || de->de_TableSize < DE_UPPERCYL) { error = DIO_ERROR_GETFSD; goto cleanup; } if (dio->inhibit) { if (!Inhibit(dio->devname, TRUE)) { error = DIO_ERROR_INHIBIT; goto cleanup; } dio->uninhibit = TRUE; /* So Cleanup() knows that it should uninhibit */ } dio->diskmp = mp = CreateMsgPort(); dio->diskiotd = iotd = CreateIORequest(dio->diskmp, sizeof(*iotd)); if (iotd == NULL) { error = DIO_ERROR_NOMEM; goto cleanup; } FbxCopyStringBSTRToC(fssm->fssm_Device, (STRPTR)devname, sizeof(devname)); if (OpenDevice((CONST_STRPTR)devname, fssm->fssm_Unit, (struct IORequest *)iotd, fssm->fssm_Flags) != 0) { DEBUGF("DIO_Setup: Failed to open %s unit %u using flags 0x%x.\n", fssm->fssm_Device, (unsigned int)fssm->fssm_Unit, (unsigned int)fssm->fssm_Flags); error = DIO_ERROR_OPENDEVICE; goto cleanup; } dio->disk_device = iotd->iotd_Req.io_Device; if (de->de_LowCyl == 0) { dio->use_full_disk = TRUE; DEBUGF("de_LowCyl == 0 => using full disk\n"); } else { UQUAD sector_size = de->de_SizeBlock * sizeof(ULONG); UQUAD cylinder_size = (UQUAD)de->de_BlocksPerTrack * (UQUAD)de->de_Surfaces * sector_size; dio->use_full_disk = FALSE; SetSectorSize(dio, sector_size); dio->partition_start = (UQUAD)de->de_LowCyl * cylinder_size; dio->partition_size = (UQUAD)(de->de_HighCyl - de->de_LowCyl + 1) * cylinder_size; dio->total_sectors = dio->partition_size / dio->sector_size; DEBUGF("partiton start: %llu partition size: %llu cylinder size: %llu sector size: %lu total sectors: %llu\n", dio->partition_start, dio->partition_size, cylinder_size, dio->sector_size, dio->total_sectors); } DEBUGF("Trying NSD query command\n"); iotd->iotd_Req.io_Command = NSCMD_DEVICEQUERY; iotd->iotd_Req.io_Data = &nsdqr; iotd->iotd_Req.io_Length = sizeof(nsdqr); bzero(&nsdqr, sizeof(nsdqr)); /* Required for usbscsi.device */ if (DoIO((struct IORequest *)iotd) == 0) { if (nsdqr.DeviceType != NSDEVTYPE_TRACKDISK) { DEBUGF("Not a trackdisk device\n"); error = DIO_ERROR_NSDQUERY; goto cleanup; } if (nsdqr.SupportedCommands != NULL) { UWORD cmd; int i = 0; while ((cmd = nsdqr.SupportedCommands[i++]) != CMD_INVALID) { if (cmd == CMD_READ) dio->cmd_support |= CMDSF_TD32; else if (cmd == ETD_READ) dio->cmd_support |= CMDSF_ETD32; else if (cmd == TD_READ64) dio->cmd_support |= CMDSF_TD64; else if (cmd == NSCMD_TD_READ64) dio->cmd_support |= CMDSF_NSD_TD64; else if (cmd == NSCMD_ETD_READ64) dio->cmd_support |= CMDSF_NSD_ETD64; else if (cmd == CMD_UPDATE) dio->cmd_support |= CMDSF_CMD_UPDATE; else if (cmd == ETD_UPDATE) dio->cmd_support |= CMDSF_ETD_UPDATE; } } } else if (iotd->iotd_Req.io_Error == IOERR_NOCMD) { DEBUGF("Not an NSD device\n"); dio->cmd_support = CMDSF_TD32|CMDSF_CMD_UPDATE; DEBUGF("Checking for TD64 support\n"); iotd->iotd_Req.io_Command = TD_READ64; iotd->iotd_Req.io_Data = NULL; iotd->iotd_Req.io_Actual = 0; iotd->iotd_Req.io_Offset = 0; iotd->iotd_Req.io_Length = 0; if (DoIO((struct IORequest *)iotd) != IOERR_NOCMD) dio->cmd_support |= CMDSF_TD64; } else { DEBUGF("NSD query command failed (error: %d)\n", (int)iotd->iotd_Req.io_Error); error = DIO_ERROR_NSDQUERY; goto cleanup; } if ((dio->cmd_support & (CMDSF_TD32|CMDSF_ETD32|CMDSF_TD64|CMDSF_NSD_TD64|CMDSF_NSD_ETD64)) == 0) { DEBUGF("No I/O commands supported\n"); error = DIO_ERROR_NSDQUERY; goto cleanup; } if (dio->cmd_support & CMDSF_ETD_UPDATE) dio->update_cmd = ETD_UPDATE; else if (dio->cmd_support & CMDSF_CMD_UPDATE) dio->update_cmd = CMD_UPDATE; else dio->update_cmd = CMD_INVALID; dio->mempool = CreatePool(MEMF_PUBLIC, 4096, 1024); if (dio->mempool == NULL) { error = DIO_ERROR_NOMEM; goto cleanup; } DIO_Update(dio); DEBUGF("DIO_Setup: %#p\n", dio); return dio; cleanup: if (dio != NULL) DIO_Cleanup(dio); error_storage = (int *)GetTagData(DIOS_Error, (Tag)NULL, tags); if (error_storage != NULL) *error_storage = error; DEBUGF("DIO_Setup failed (error: %d)\n", error); return NULL; }
// Open a disk for IO DiskHandle *LIBFUNC L_OpenDisk( REG(a0, char *disk), REG(a1, struct MsgPort *port)) { DiskHandle *handle; struct DosList *dl; unsigned long blocks; char *ptr; // Allocate handle if (!(handle=AllocVec(sizeof(DiskHandle),MEMF_CLEAR))) return 0; // Copy name, strip colon stccpy(handle->dh_name,disk,31); if ((ptr=strchr(handle->dh_name,':'))) *ptr=0; // Lock DOS list dl=LockDosList(LDF_DEVICES|LDF_READ); // Find entry if (!(dl=FindDosEntry(dl,handle->dh_name,LDF_DEVICES))) { // Not found UnLockDosList(LDF_DEVICES|LDF_READ); FreeVec(handle); return 0; } // Add colon back on strcat(handle->dh_name,":"); // Get pointer to startup message and geometry handle->dh_startup=(struct FileSysStartupMsg *)BADDR(dl->dol_misc.dol_handler.dol_Startup); handle->dh_geo=(struct DosEnvec *)BADDR(handle->dh_startup->fssm_Environ); // Shortcuts to root block and blocksize blocks=handle->dh_geo->de_BlocksPerTrack* handle->dh_geo->de_Surfaces* (handle->dh_geo->de_HighCyl-handle->dh_geo->de_LowCyl+1); handle->dh_root=(blocks-1+handle->dh_geo->de_Reserved)>>1; handle->dh_blocksize=handle->dh_geo->de_SizeBlock<<2; // Get real device name L_BtoCStr((BPTR)handle->dh_startup->fssm_Device,handle->dh_device,32); // Get information #ifdef __AROS__ if (((struct Library *)DOSBase)->lib_Version<50) { //handle->dh_result=Info(dl->dol_Lock,&handle->dh_info); BPTR lock; handle->dh_result=0; if ((lock=Lock(handle->dh_name,SHARED_LOCK))) { handle->dh_result=Info(lock,&handle->dh_info); UnLock(lock); } } else #endif handle->dh_result=DoPkt(dl->dol_Task,ACTION_DISK_INFO,MKBADDR(&handle->dh_info),0,0,0,0); // Unlock dos list UnLockDosList(LDF_DEVICES|LDF_READ); // Create message port if needed if (!port) { if (!(handle->dh_port=CreateMsgPort())) { FreeVec(handle); return 0; } port=handle->dh_port; } // Create IO request if (!(handle->dh_io=(struct IOExtTD *)CreateIORequest(port,sizeof(struct IOExtTD)))) { if (handle->dh_port) DeleteMsgPort(handle->dh_port); FreeVec(handle); return 0; } // Open device if (OpenDevice( handle->dh_device, handle->dh_startup->fssm_Unit, (struct IORequest *)handle->dh_io, handle->dh_startup->fssm_Flags)) { // Failed to open L_CloseDisk(handle); return 0; } return handle; }
LONG DoNameAsynch(struct IOFileSys *iofs, STRPTR name, struct DosLibrary *DOSBase) { STRPTR volname, pathname, s1 = NULL; BPTR cur, lock = (BPTR)NULL; struct DosList *dl; struct Device *device; struct Unit *unit; struct FileHandle *fh; struct Process *me = (struct Process *)FindTask(NULL); if (!Strnicmp(name, "PROGDIR:", 8) && me->pr_HomeDir) { cur = me->pr_HomeDir; volname = NULL; pathname = name + 8; } else if (*name == ':') { cur = me->pr_CurrentDir; volname = NULL; pathname = name + 1; } else { /* Copy volume name */ cur = me->pr_CurrentDir; s1 = name; pathname = name; volname = NULL; while (*s1) { if (*s1++ == ':') { volname = (STRPTR)AllocMem(s1-name, MEMF_ANY); if (volname == NULL) { return ERROR_NO_FREE_STORE; } CopyMem(name, volname, s1 - name - 1); volname[s1 - name - 1] = '\0'; pathname = s1; break; } } } if (!volname && !cur && !DOSBase->dl_SYSLock) { return ERROR_OBJECT_NOT_FOUND; } dl = LockDosList(LDF_ALL | LDF_READ); if (volname != NULL) { /* Find logical device */ dl = FindDosEntry(dl, volname, LDF_ALL); if (dl == NULL) { UnLockDosList(LDF_ALL | LDF_READ); FreeMem(volname, s1 - name); return ERROR_DEVICE_NOT_MOUNTED; } else if (dl->dol_Type == DLT_LATE) { lock = Lock(dl->dol_misc.dol_assign.dol_AssignName, SHARED_LOCK); UnLockDosList(LDF_ALL | LDF_READ); if (lock != NULL) { AssignLock(volname, lock); dl = LockDosList(LDF_ALL | LDF_READ); dl = FindDosEntry(dl, volname, LDF_ALL); if (dl == NULL) { UnLockDosList(LDF_ALL | LDF_READ); FreeMem(volname, s1 - name); return ERROR_DEVICE_NOT_MOUNTED; } device = dl->dol_Ext.dol_AROS.dol_Device; unit = dl->dol_Ext.dol_AROS.dol_Unit; } else { FreeMem(volname, s1 - name); return IoErr(); } } else if (dl->dol_Type == DLT_NONBINDING) { lock = Lock(dl->dol_misc.dol_assign.dol_AssignName, SHARED_LOCK); fh = (struct FileHandle *)BADDR(lock); if (fh != NULL) { device = fh->fh_Device; unit = fh->fh_Unit; } else { UnLockDosList(LDF_ALL | LDF_READ); FreeMem(volname, s1 - name); return IoErr(); } } else { device = dl->dol_Ext.dol_AROS.dol_Device; unit = dl->dol_Ext.dol_AROS.dol_Unit; } } else if (cur) { fh = (struct FileHandle *)BADDR(cur); device = fh->fh_Device; unit = fh->fh_Unit; } else { #if 0 /* stegerg: ?? */ device = DOSBase->dl_NulHandler; unit = DOSBase->dl_NulLock; #else fh = (struct FileHandle *)BADDR(DOSBase->dl_SYSLock); device = fh->fh_Device; unit = fh->fh_Unit; #endif } iofs->IOFS.io_Device = device; iofs->IOFS.io_Unit = unit; iofs->io_Union.io_NamedFile.io_Filename = pathname; if (volname != NULL) { FreeMem(volname, s1 - name); } return 0; }
int access ( /* SYNOPSIS */ const char *path, int mode) /* FUNCTION Check access permissions of a file or pathname INPUTS path - the path of the file being checked mode - the bitwise inclusive OR of the access permissions to be checked: W_OK - for write permission R_OK - for readpermissions X_OK - for execute permission F_OK - Just to see whether the file exists RESULT If path cannot be found or if any of the desired access modes would not be granted, then a -1 value is returned; otherwise a 0 value is returned. NOTES EXAMPLE BUGS SEE ALSO open(), ftruncate() INTERNALS ******************************************************************************/ { BPTR lock = NULL; struct FileInfoBlock *fib = NULL; int result = -1; char vol[32]; struct DosList *dl = NULL; if (!path) /* safety check */ { errno = EFAULT; return -1; } if (!strlen(path)) /* empty path */ { errno = ENOENT; return -1; } /* Check if the volume exists. Calling Lock on non-existing volume will bring up System Requester */ if (SplitName(__path_u2a(path), ':', vol, 0, sizeof(vol)-1) != -1) { if(strcmp(vol, "PROGDIR") != 0) { dl = LockDosList(LDF_ALL | LDF_READ); dl = FindDosEntry(dl, vol, LDF_ALL); UnLockDosList(LDF_ALL | LDF_READ); /* Volume / Assign / Device not found */ if (dl == NULL) { errno = ENOENT; return -1; } } } /* Create a lock and examine a lock */ lock = Lock(__path_u2a(path), SHARED_LOCK); if (lock == NULL) { errno = IoErr2errno(IoErr()); return -1; } fib = AllocDosObject(DOS_FIB, NULL); if (!fib) { errno = IoErr2errno(IoErr()); UnLock(lock); return -1; } if (Examine(lock, fib)) { /* Notice : protection flags are 'low-active' (0 means access is granted) */ result = 0; if ((mode & R_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_READ))) { errno = EACCES; result = -1; } if ((mode & W_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_WRITE))) { errno = EACCES; result = -1; } if ((mode & X_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_EXECUTE))) { errno = EACCES; result = -1; } } else { errno = EBADF; result = -1; } FreeDosObject(DOS_FIB, fib); fib = NULL; UnLock(lock); return result; }
/* Output: 0 - no mount (no partition change) 1 - mount that device 2 - reboot not really neccessary (FS not so important things changed like de_Mask) 3 - reboot neccessary (FS important things changed like de_LowCyl) */ WORD checkMount(struct HDTBPartition *table, STRPTR name, struct DosEnvec *de) { WORD retval = 1; struct DosList *dl; struct DeviceNode *entry; ULONG i; D(bug("[HDToolBox] checkMount('%s')\n", name)); dl = LockDosList(LDF_READ | LDF_DEVICES); if (dl) { entry = (struct DeviceNode *)FindDosEntry(dl, name, LDF_DEVICES); if (entry) { struct FileSysStartupMsg *fssm; struct DosEnvec *d_de; STRPTR devname; fssm = (struct FileSysStartupMsg *)BADDR(entry->dn_Startup); devname = AROS_BSTR_ADDR(fssm->fssm_Device); if ( (fssm->fssm_Unit != table->hd->unit) || (strcmp(devname, table->hd->devname)) ) { retval = 3; /* better do a reboot */ } else { d_de = (struct DosEnvec *)BADDR(fssm->fssm_Environ); i = getOffset(table->ph); if ( (d_de->de_SizeBlock != de->de_SizeBlock) || (d_de->de_Reserved != de->de_Reserved) || (d_de->de_PreAlloc != de->de_PreAlloc) || (d_de->de_LowCyl != (de->de_LowCyl+i)) || (d_de->de_HighCyl != (de->de_HighCyl+i)) || (d_de->de_DosType != de->de_DosType) || ( ( /* at least one has de_BootBocks */ (d_de->de_TableSize>=DE_BOOTBLOCKS) || (de->de_TableSize>=DE_BOOTBLOCKS) ) && ( /* if one has no de_BootBlock assume de_BootBlock change */ (d_de->de_TableSize<DE_BOOTBLOCKS) || (de->de_TableSize<DE_BOOTBLOCKS) ) ) || ( /* both have de_BootBlocks */ (d_de->de_TableSize>=DE_BOOTBLOCKS) && (de->de_TableSize>=DE_BOOTBLOCKS) && (d_de->de_BootBlocks != de->de_BootBlocks) ) ) { retval = 3; } else if ( (d_de->de_NumBuffers != de->de_NumBuffers) || (d_de->de_BufMemType != de->de_BufMemType) || (d_de->de_MaxTransfer != de->de_MaxTransfer) || (d_de->de_Mask != de->de_Mask) || (d_de->de_BootPri != de->de_BootPri) ) { retval = 2; } else retval = 0; } } UnLockDosList(LDF_READ | LDF_DEVICES); } return retval; }