==== FS_CHDIR ==== **Purpose** Change or verify the directory path for the requesting process **Calling Sequence** int far pascal FS_CHDIR(flag, pcdfsi, pcdfsd, pDir, iCurDirEnd) unsigned short flag; struct cdsfi far * pcdfsi; struct cdfsd far * pcdfsd; char far * pDir; unsigned short iCurDirEnd; **Where** ^flag ^indicates what action is to be taken on the directory. ^ |//flag// == 0 |indicates that an explicit directory-change request has been made. | |//flag// == 1 |indicates that the working directory needs to be verified. | |//flag// == 2 |indicates that this reference to a directory is being freed. | The //flag// passed to the FSD will have a valid value. //pcdfsi// is a pointer to a file-system-independent working directory structure. * For //flag// == 0, this pointer points to the previous current directory on the drive. * For //flag// == 1, this pointer points to the most recent working directory on the drive. The cdi_curdir field contains the text of the directory that is to be verified. * For //flag// == 2, this pointer is null. The FSD must never modify the //cdfsi//. The OS/2 kernel handles all updates. //pcdfsd// is a pointer to a file-system-dependent working directory structure. This is a place for the FSD to store information about the working directory. For //flag// == 0 or 1, this is the information left there by the FSD. The FSD is expected to update this information if the directory exists. For //flag// == 2, this is the information left there by the FSD. //pDir// is a pointer to directory text. For //flag// == 0, this is the pointer to the directory. For //flag// == 1 or //flag// == 2, this pointer is null. The FSD does not need to verify this pointer. //iCurDirEnd// is the index of the end of the current directory in //pDir//. This is used to optimize FSD path processing. If //iCurDirEnd// == -1, there is no current directory relevant to the directory text, that is, a device. This parameter only has meaning for //flag// == 0. **Remarks** The FSD should cache no information when the directory is the root. Root directories are a special case. They always exist, and never need validation. The OS/2 kernel does not pass root directory requests to the FSD. An FSD is not allowed to cache any information in the cdfsd data structure for a root directory. Under normal conditions, the kernel does not save the CDS for a root directory and builds one from scratch when it is needed. (One exception is where a validate CDS fails, and the kernel sets it to the root, and zeroes out the cdfsd data structure. This CDS is saved and is cleaned up later.) The following is information about the exact state of the cdfsi and cdfsd data structures passed to the FSD for each flag value and guidelines about what an FSD should do upon receiving an FS_CHDIR call: IF (flag == 0) /* Set new Current Directory */ pcdfsi, pcdfsd = copy of CDS we're starting from; may be useful as starting point for verification. cdfsi contents: hVPB - handle of Volume Parameter Block mapped to this drive end - end of root portion of CurDir flags - various flags (indicating state of cdfsd) IsValid - cdfsd is unknown format (ignore contents) IsValid == 0x80 IsRoot - cdfsd is meaningless if CurDir = root (not kept) IsRoot == 0x40 IsCurrent - cdfsd is know format, but may not be current (medium may have been changed). IsCurrent == 0x20 text - Current Directory Text icurdir = if Current Directory is in the path of the new Current Directory, this is the index to the end of the Current Directory. If not, this is -1 (Current Directory does not apply). pDir = path to verify as legal directory THEN Validate path named in pDir. /* This means both that it exists AND that it is a directory. pcdfsi, pcdfsd, icurdir give old CDS, which may allow optimization */ IF (Validate succeeds) IF (pDir != ROOT) Store any cache information in area pointed to by pcdfsd. ELSE Do Nothing. /* Area pointed to by pcdfsd will be thrown away, so don't bother storing into it */ Return success. ELSE Return failure. /* Kernel will create new CDS using pDir data and pcdfsd data. If the old CDS is valid, the kernel will take care of cleaning it up. The FSD must not edit any structure other than the *Pcdfsd area, with which it may do as it chooses. */ /* flag == 0 */ ELSE IF (flag == 1) /* Validate current CDS structure */ pcdfsi = pointer to copy of cdfsi of interest. pcdfsd = pointer to copy of cdfsd. Flags in cdfsi indicate the state of this cdfsd. It may be: (1) completely invalid (unknown format), (2) known format, but non-current information, (3) completely valid, or (4) all zero (root). THEN Validate that CDS still describes a legal directory (using cdi_text). IF (valid) Update cdfsd if necessary. Return success. /* kernel will copy cdfsd into real CDS */ ELSE IF (cdi_isvalid) Release any resources associated with cdfsd. /* kernel will force Current Directory to root, and will zero out cdfsd in real CDS */ Return failure. /* The FSD must not modify any structure other than the cdfsd pointed to by pcdfsd. */ ELSE IF (flag == 2) /* previous CDS no longer in use; being freed */ pcdfsd = pointer to copy of cdfsd of CDS being freed. THEN Release any resources associated with the CDS. /* For example, if cdfsd (where pcdfsd points) contains a pointer to some FSD private structure associated with the CDS, that structure should be freed. */ /* kernel will not retain the cdfsd */