Prev: IIS + ISAPI + EXE + Kernel Namespace + User Accounts + Security Model
Next: IOCP: Sockets and Async RPC
From: a on 2 May 2010 22:50 Hi I suggest that you read the source code of CRT to understand the behavior: int __cdecl _chdrive ( int drive ) { int retval; char newdrive[3]; if (drive < 1 || drive > 26) { _doserrno = ERROR_INVALID_DRIVE; _VALIDATE_RETURN(("Invalid Drive Index",0), EACCES, -1); } _mlock( _ENV_LOCK ); __try { newdrive[0] = (char)('A' + (char)drive - (char)1); newdrive[1] = ':'; newdrive[2] = '\0'; /* * Set new drive. If current directory on new drive exists, it * will become the cwd. Otherwise defaults to root directory. */ if ( SetCurrentDirectory((LPSTR)newdrive) ) retval = 0; else { _dosmaperr(GetLastError()); retval = -1; } } __finally { _munlock( _ENV_LOCK ); } return retval; } _TSCHAR * __cdecl _tgetdcwd ( int drive, _TSCHAR *pnbuf, int maxlen ) { _TSCHAR *p; _TSCHAR drvstr[4]; int ret, count; _TSCHAR *pname; /* only used as argument to GetFullPathName */ if ( drive != 0 ) { /* * Not the default drive - make sure it's valid. */ if ( !_validdrive(drive) ) { _doserrno = ERROR_INVALID_DRIVE; _VALIDATE_RETURN(("Invalid Drive",0), EACCES, NULL); } } else { /* Get the drive index of the default drive */ drive = _getdrive(); } /* If pnbuf is NULL, we pass 0 in both the 2nd & 3rd parameter to find required length to allocate */ if(pnbuf) { _VALIDATE_RETURN( (maxlen > 0), EINVAL, NULL); count = maxlen; pnbuf[0] = 0; } else count = 0; /* * Get the current directory string on that drive and its length */ if(drive!=0) { drvstr[0] = _T('A') - 1 + drive; drvstr[1] = _T(':'); drvstr[2] = _T('.'); drvstr[3] = _T('\0'); } else { drvstr[0] = _T('.'); drvstr[1] = _T('\0'); } ret = GetFullPathName( drvstr, count, pnbuf, &pname ); if(ret == 0) { _dosmaperr( GetLastError() ); return NULL; } if( pnbuf != NULL ) { if(ret < count) { /* GetFullPathName always returns a value less than that passed in if successful i.e. we got the required dir */ return pnbuf; } errno = ERANGE; *pnbuf = 0; return NULL; } /* The code comes here only if pnbuf was NULL Allocate the required memory & call GetFullPathName again*/ maxlen = __max(ret, maxlen) ; #ifdef _DEBUG if( (p = (_TSCHAR *)_calloc_dbg( maxlen, sizeof(_TSCHAR), nBlockUse, szFileName, nLine)) == NULL) { #else /* _DEBUG */ if( (p = (_TSCHAR *)calloc( maxlen, sizeof(_TSCHAR))) == NULL) { #endif /* _DEBUG */ errno = ENOMEM; _doserrno = E_nomem; return NULL; } ret = GetFullPathName( drvstr, maxlen, p, &pname ); if(ret == 0 || ret >= maxlen) { _dosmaperr( GetLastError() ); return NULL; } return p; } "David F." <df2705(a)community.nospam> wrote in message news:DD36AA91-8089-4202-8163-B171DBDB80F8(a)microsoft.com... > For an environment where that makes since .. I didn't want to have to > getdrive / setdrive but I guess I'll have to do something like that. > > "Leo Davidson" <leonudeldavidson(a)googlemail.com> wrote in message > news:610b6b83-125c-4698-b2f0-d34a9feab4d6(a)s29g2000yqd.googlegroups.com... > On Apr 30, 7:57 pm, "David F." <df2...(a)community.nospam> wrote: > > >> From Docs: "If a new drive letter is specified in dirname, the default >> drive >> letter is changed as well" ... I don't want it to do that. > > I think you'll have to _chdir to the new path, then _chdrive back to > the old drive/path if you want to do that. > > I'm curious why you want to do an MS-DOS-style _chdir for a drive you > are not using, and without affecting the actual current dir? > > Is this for your own code or is some other component forcing you to do > these contortions? >
From: Leo Davidson on 3 May 2010 04:23 On May 3, 3:50 am, "a" <a...(a)a.com> wrote: > I suggest that you read the source code of CRT to understand the behavior: I always forget the CRT source is available. :) The most interesting source is that of _chdir, which shows it is doing extra bookkeeping beyond what SetCurrentDirectory does, as I suspected (although the way the extra info is stored and the fact that other Win32 APIs use it automatically did surprise me). From chdir.c: * If the new current directory path is NOT a UNC path, we must * update the OS environment variable specifying the current * directory for what is now current drive. To do this, get the * full current directory, build the environment variable string * and call SetEnvironmentVariable(). We need to do this because * SetCurrentDirectory does not (i.e., does not update the * current-directory-on-drive environment variables) and other * functions (fullpath, spawn, etc) need them to be set. * * If associated with a 'drive', the current directory should * have the form of the example below: * * D:\nt\private\mytests * * so that the environment variable should be of the form: * * =D:=D:\nt\private\mytests
From: Leo Davidson on 6 May 2010 12:07 On May 3, 9:23 am, Leo Davidson <leonudeldavid...(a)googlemail.com> wrote: > * so that the environment variable should be of the form: > * > * =D:=D:\nt\private\mytests As luck would have it, Raymond Chen just posted some more info/history about this stuff on his OldNewThing blog: http://blogs.msdn.com/oldnewthing/archive/2010/05/06/10008132.aspx
First
|
Prev
|
Pages: 1 2 Prev: IIS + ISAPI + EXE + Kernel Namespace + User Accounts + Security Model Next: IOCP: Sockets and Async RPC |