Skip to content

Commit 61492ec

Browse files
committed
SFTP List
1. In Windows build, when getting the file list for "/", cache a copy of the known drive letters. 2. When supplying the drives for Windows, use the cached copies.
1 parent 2be99a2 commit 61492ec

File tree

2 files changed

+55
-19
lines changed

2 files changed

+55
-19
lines changed

src/wolfsftp.c

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

wolfssh/internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,11 @@ struct WOLFSSH {
717717
struct WS_SFTP_SEND_WRITE_STATE* sendWriteState;
718718
struct WS_SFTP_GET_HANDLE_STATE* getHandleState;
719719
struct WS_SFTP_RENAME_STATE* renameState;
720+
#ifdef USE_WINDOWS_API
721+
char driveList[26];
722+
word16 driveListCount;
723+
word16 driveIdx;
724+
#endif
720725
#endif
721726

722727
#ifdef WOLFSSH_AGENT

0 commit comments

Comments
 (0)