@@ -2303,30 +2303,52 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
23032303 WMEMCPY (dirName , data + idx , sz );
23042304 dirName [sz ] = '\0' ;
23052305
2306- if (sz > MAX_PATH - 2 ) {
2307- WLOG (WS_LOG_SFTP , "Path name is too long." );
2308- return WS_FATAL_ERROR ;
2306+ /* Special case in Windows for the root directory above the drives. */
2307+ if (dirName [0 ] == '/' && dirName [1 ] == 0 ) {
2308+ DWORD drives , mask ;
2309+ UINT driveType ;
2310+ char driveName [] = " :\\" ;
2311+ int i ;
2312+
2313+ WMEMSET (ssh -> driveList , 0 , sizeof ssh -> driveList );
2314+ drives = GetLogicalDrives ();
2315+ for (i = 0 , mask = 1 ; i < 26 ; i ++ , mask <<= 1 ) {
2316+ if (drives & mask ) {
2317+ driveName [0 ] = 'A' + i ;
2318+ driveType = GetDriveTypeA (driveName );
2319+ if (driveType == DRIVE_FIXED || driveType == DRIVE_REMOTE ) {
2320+ ssh -> driveList [ssh -> driveListCount ++ ] = driveName [0 ];
2321+ }
2322+ }
2323+ }
2324+ ssh -> driveIdx = 0 ;
23092325 }
2310- WSTRNCPY (name , dirName , MAX_PATH );
2311- WSTRNCAT (name , "/*" , MAX_PATH );
2326+ else {
2327+ if (sz > MAX_PATH - 2 ) {
2328+ WLOG (WS_LOG_SFTP , "Path name is too long." );
2329+ return WS_FATAL_ERROR ;
2330+ }
2331+ WSTRNCPY (name , dirName , MAX_PATH );
2332+ WSTRNCAT (name , "/*" , MAX_PATH );
23122333
2313- /* get directory handle - see if directory exists */
2314- findHandle = (HANDLE )WS_FindFirstFileA (name ,
2315- realName , sizeof (realName ), & isDir , ssh -> ctx -> heap );
2316- if (findHandle == INVALID_HANDLE_VALUE || !isDir ) {
2334+ /* get directory handle - see if directory exists */
2335+ findHandle = (HANDLE )WS_FindFirstFileA (name ,
2336+ realName , sizeof (realName ), & isDir , ssh -> ctx -> heap );
2337+ if (findHandle == INVALID_HANDLE_VALUE || !isDir ) {
23172338
2318- WLOG (WS_LOG_SFTP , "Error with opening directory" );
2319- WFREE (dirName , ssh -> ctx -> heap , DYNTYPE_BUFFER );
2339+ WLOG (WS_LOG_SFTP , "Error with opening directory" );
2340+ WFREE (dirName , ssh -> ctx -> heap , DYNTYPE_BUFFER );
23202341
2321- if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
2322- "Unable To Open Directory" , "English" , NULL , & outSz )
2323- != WS_SIZE_ONLY ) {
2324- return WS_FATAL_ERROR ;
2342+ if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
2343+ "Unable To Open Directory" , "English" , NULL , & outSz )
2344+ != WS_SIZE_ONLY ) {
2345+ return WS_FATAL_ERROR ;
2346+ }
2347+ ret = WS_BAD_FILE_E ;
23252348 }
2326- ret = WS_BAD_FILE_E ;
2349+ if (findHandle != NULL && findHandle != INVALID_HANDLE_VALUE )
2350+ FindClose (findHandle );
23272351 }
2328- if (findHandle != NULL && findHandle != INVALID_HANDLE_VALUE )
2329- FindClose (findHandle );
23302352
23312353 (void )reqId ;
23322354
@@ -2708,7 +2730,16 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
27082730 return WS_BAD_ARGUMENT ;
27092731 }
27102732
2711- if (* dir == INVALID_HANDLE_VALUE ) {
2733+ /* special case of getting drives at "/" */
2734+ if (dirName [0 ] == "/" && dirName [1 ] == 0 ) {
2735+ if (ssh -> driveIdx >= ssh -> driveListCount )
2736+ return WS_FATAL_ERROR ;
2737+ realFileName [0 ] = ssh -> driveList [ssh -> driveIdx ++ ];
2738+ realFileName [1 ] = ':' ;
2739+ realFileName [2 ] = '/' ;
2740+ realFileName [3 ] = '\0' ;
2741+ }
2742+ else if (* dir == INVALID_HANDLE_VALUE ) {
27122743 char name [MAX_PATH ];
27132744 word32 nameLen = (word32 )WSTRLEN (dirName );
27142745
0 commit comments