301 lines
6.4 KiB
C
301 lines
6.4 KiB
C
|
/* demdir.c - SVC handlers for directory calls
|
||
|
*
|
||
|
* DemCreateDir
|
||
|
* DemDeleteDir
|
||
|
* DemQueryCurrentDir
|
||
|
* DemSetCurrentDir
|
||
|
*
|
||
|
* Modification History:
|
||
|
*
|
||
|
* Sudeepb 04-Apr-1991 Created
|
||
|
*/
|
||
|
|
||
|
#include "dem.h"
|
||
|
#include "demmsg.h"
|
||
|
|
||
|
#include <softpc.h>
|
||
|
|
||
|
/* demCreateDir - Create a directory
|
||
|
*
|
||
|
*
|
||
|
* Entry - Client (DS:DX) directory name to create
|
||
|
* Client (BX:SI) EAs (NULL if no EAs)
|
||
|
*
|
||
|
* Exit
|
||
|
* SUCCESS
|
||
|
* Client (CY) = 0
|
||
|
*
|
||
|
* FAILURE
|
||
|
* Client (CY) = 1
|
||
|
* Client (AX) = system status code
|
||
|
*
|
||
|
*
|
||
|
* Notes : Extended Attributes is not yet taken care of.
|
||
|
*/
|
||
|
|
||
|
VOID demCreateDir (VOID)
|
||
|
{
|
||
|
LPSTR lpDir;
|
||
|
#ifdef DBCS /* demCreateDir() for CSNW */
|
||
|
CHAR achPath[MAX_PATH];
|
||
|
#endif /* DBCS */
|
||
|
|
||
|
// EAs not yet implemented
|
||
|
if (getBX() || getSI()){
|
||
|
demPrintMsg (MSG_EAS);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
lpDir = (LPSTR) GetVDMAddr (getDS(),getDX());
|
||
|
|
||
|
#ifdef DBCS /* demCreateDir() for CSNW */
|
||
|
/*
|
||
|
* convert Netware path to Dos path
|
||
|
*/
|
||
|
ConvNwPathToDosPath(achPath,lpDir);
|
||
|
lpDir = achPath;
|
||
|
#endif /* DBCS */
|
||
|
|
||
|
if(CreateDirectoryOem (lpDir,NULL) == FALSE){
|
||
|
demClientError(INVALID_HANDLE_VALUE, *lpDir);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
setCF(0);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* demDeleteDir - Create a directory
|
||
|
*
|
||
|
*
|
||
|
* Entry - Client (DS:DX) directory name to create
|
||
|
*
|
||
|
* Exit
|
||
|
* SUCCESS
|
||
|
* Client (CY) = 0
|
||
|
*
|
||
|
* FAILURE
|
||
|
* Client (CY) = 1
|
||
|
* Client (AX) = system status code
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
VOID demDeleteDir (VOID)
|
||
|
{
|
||
|
LPSTR lpDir;
|
||
|
|
||
|
lpDir = (LPSTR) GetVDMAddr (getDS(),getDX());
|
||
|
|
||
|
if (RemoveDirectoryOem(lpDir) == FALSE){
|
||
|
demClientError(INVALID_HANDLE_VALUE, *lpDir);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
setCF(0);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* demQueryCurrentDir - Verifies current dir provided in CDS structure
|
||
|
* for $CURRENT_DIR
|
||
|
*
|
||
|
* First Validates Media, if invalid -> i24 error
|
||
|
* Next Validates Path, if invalid set path to root (not an error)
|
||
|
*
|
||
|
* Entry - Client (DS:SI) Buffer to CDS path to verify
|
||
|
* Client (AL) Physical Drive in question (A=0, B=1, ...)
|
||
|
*
|
||
|
* Exit
|
||
|
* SUCCESS
|
||
|
* Client (CY) = 0
|
||
|
*
|
||
|
* FAILURE
|
||
|
* Client (CY) = 1 , I24 drive invalid
|
||
|
*/
|
||
|
VOID demQueryCurrentDir (VOID)
|
||
|
{
|
||
|
PCDS pcds;
|
||
|
DWORD dw;
|
||
|
CHAR chDrive;
|
||
|
CHAR pPath[]="?:\\";
|
||
|
CHAR EnvVar[] = "=?:";
|
||
|
|
||
|
pcds = (PCDS)GetVDMAddr(getDS(),getSI());
|
||
|
|
||
|
// validate media
|
||
|
chDrive = getAL() + 'A';
|
||
|
pPath[0] = chDrive;
|
||
|
dw = GetFileAttributesOem(pPath);
|
||
|
if (dw == 0xFFFFFFFF || !(dw & FILE_ATTRIBUTE_DIRECTORY))
|
||
|
{
|
||
|
demClientError(INVALID_HANDLE_VALUE, chDrive);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// if invalid path, set path to the root
|
||
|
// reset CDS, and win32 env for win32
|
||
|
dw = GetFileAttributesOem(pcds->CurDir_Text);
|
||
|
if (dw == 0xFFFFFFFF || !(dw & FILE_ATTRIBUTE_DIRECTORY))
|
||
|
{
|
||
|
strcpy(pcds->CurDir_Text, pPath);
|
||
|
pcds->CurDir_End = 2;
|
||
|
EnvVar[1] = chDrive;
|
||
|
SetEnvironmentVariableOem(EnvVar,pPath);
|
||
|
}
|
||
|
|
||
|
setCF(0);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* demSetCurrentDir - Set the current directory
|
||
|
*
|
||
|
*
|
||
|
* Entry - Client (DS:DX) directory name
|
||
|
* Dos default drive (AL) , CurDrv, where 1 == A.
|
||
|
*
|
||
|
* Exit
|
||
|
* SUCCESS
|
||
|
* Client (CY) = 0
|
||
|
*
|
||
|
* FAILURE
|
||
|
* Client (CY) = 1
|
||
|
* Client (AX) = system status code
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
extern NTSTATUS demSetCurrentDirectoryLCDS(UCHAR, LPSTR);
|
||
|
|
||
|
VOID demSetCurrentDir (VOID)
|
||
|
{
|
||
|
DWORD dw;
|
||
|
LPSTR lpBuf;
|
||
|
CHAR EnvVar[] = "=?:";
|
||
|
CHAR ch;
|
||
|
PCDS pCDS;
|
||
|
BOOL bLongDirName;
|
||
|
|
||
|
|
||
|
lpBuf = (LPSTR) GetVDMAddr (getDS(),getDX());
|
||
|
ch = (CHAR) toupper(*(PCHAR)lpBuf);
|
||
|
if (ch < 'A' || ch > 'Z'){
|
||
|
setCF(1);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// got the darn cds ptr
|
||
|
pCDS = (PCDS)GetVDMAddr(getES(), getDI());
|
||
|
|
||
|
// now see if the directory name is too long
|
||
|
bLongDirName = (strlen(lpBuf) > DIRSTRLEN);
|
||
|
//
|
||
|
// if the current dir is for the default drive
|
||
|
// set the win32 process's current drive,dir. This
|
||
|
// will open an NT dir handle, and verify that it
|
||
|
// exists.
|
||
|
//
|
||
|
|
||
|
if (ch == getAL() + 'A') {
|
||
|
if (SetCurrentDirectoryOem (lpBuf) == FALSE){
|
||
|
demClientError(INVALID_HANDLE_VALUE, ch);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// if its not for the default drive, we still need
|
||
|
// to verify that the dir\drive combinations exits.
|
||
|
//
|
||
|
|
||
|
else {
|
||
|
dw = GetFileAttributesOem(lpBuf);
|
||
|
if (dw == 0xFFFFFFFF || !(dw & FILE_ATTRIBUTE_DIRECTORY))
|
||
|
{
|
||
|
demClientError(INVALID_HANDLE_VALUE, ch);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
EnvVar[1] = *(PCHAR)lpBuf;
|
||
|
if(SetEnvironmentVariableOem ((LPSTR)EnvVar,lpBuf) == FALSE)
|
||
|
setCF(1);
|
||
|
else {
|
||
|
// this is what '95 is doing for dos apps.
|
||
|
// upon a getcurdir call -- it is going to be invalid
|
||
|
|
||
|
// if we came here -- update a long directory as well
|
||
|
demSetCurrentDirectoryLCDS((UCHAR)(ch - 'A'), lpBuf);
|
||
|
|
||
|
strncpy(pCDS->CurDir_Text, lpBuf, DIRSTRLEN);
|
||
|
if (bLongDirName) {
|
||
|
setCF(1);
|
||
|
}
|
||
|
else {
|
||
|
setCF(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
#ifdef DBCS /* ConvNwPathToDosPath() for CSNW */
|
||
|
//
|
||
|
// TO BT LATER and IT SHOULD BE...
|
||
|
//
|
||
|
// This routine does change Novell-J-laized file name to
|
||
|
// our well-known filename, but this code is only for the
|
||
|
// request from Novell utilities. these code should be
|
||
|
// laied onto nw16.exe (nw\nw16\tsr\resident.asm).
|
||
|
//
|
||
|
VOID ConvNwPathToDosPath(CHAR *lpszDos,CHAR *lpszNw)
|
||
|
{
|
||
|
/*
|
||
|
* check parameter
|
||
|
*/
|
||
|
if((lpszDos == NULL) || (lpszNw == NULL)) return;
|
||
|
|
||
|
/*
|
||
|
* copy data from vdm buffer to our local buffer
|
||
|
*/
|
||
|
strcpy(lpszDos,lpszNw);
|
||
|
|
||
|
/*
|
||
|
* replace the specified character
|
||
|
*/
|
||
|
while(*lpszDos) {
|
||
|
|
||
|
if(IsDBCSLeadByte(*lpszDos)) {
|
||
|
/*
|
||
|
* This is a DBCS character, check trailbyte is 0x5C or not.
|
||
|
*/
|
||
|
lpszDos++;
|
||
|
|
||
|
if( *lpszDos == 0x13 ) {
|
||
|
*lpszDos++ = (UCHAR)0x5C;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
switch((UCHAR)*lpszDos) {
|
||
|
case 0x10 :
|
||
|
*lpszDos = (UCHAR)0xBF;
|
||
|
break;
|
||
|
case 0x11 :
|
||
|
*lpszDos = (UCHAR)0xAE;
|
||
|
break;
|
||
|
case 0x12 :
|
||
|
*lpszDos = (UCHAR)0xAA;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* next char
|
||
|
*/
|
||
|
lpszDos++;
|
||
|
}
|
||
|
}
|
||
|
#endif /* DBCS */
|