Skip to content

Commit 85f6444

Browse files
authored
Add implementation of Sys.IO.DriveInfo (nanoframework#2912)
1 parent 12abaab commit 85f6444

File tree

8 files changed

+312
-5
lines changed

8 files changed

+312
-5
lines changed

CMake/Modules/FindSystem.IO.FileSystem.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(System.IO.FileSystem_SRCS
2424

2525
nf_sys_io_filesystem_nanoFramework_System_IO_FileSystem_SDCard.cpp
2626
nf_sys_io_filesystem_System_IO_Directory.cpp
27+
nf_sys_io_filesystem_System_IO_DriveInfo.cpp
2728
nf_sys_io_filesystem_System_IO_File.cpp
2829
nf_sys_io_filesystem_System_IO_FileStream.cpp
2930

src/System.IO.FileSystem/nf_sys_io_filesystem.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ static const CLR_RT_MethodHandler method_lookup[] =
7272
NULL,
7373
NULL,
7474
NULL,
75+
Library_nf_sys_io_filesystem_System_IO_DriveInfo::DriveInfoNative___VOID__STRING,
76+
NULL,
77+
Library_nf_sys_io_filesystem_System_IO_DriveInfo::Format___STATIC__VOID__STRING,
78+
Library_nf_sys_io_filesystem_System_IO_DriveInfo::GetDrivesNative___STATIC__SZARRAY_SystemIODriveInfo,
79+
NULL,
80+
NULL,
81+
NULL,
82+
NULL,
83+
NULL,
84+
NULL,
85+
NULL,
7586
NULL,
7687
NULL,
7788
NULL,
@@ -133,14 +144,16 @@ static const CLR_RT_MethodHandler method_lookup[] =
133144
NULL,
134145
NULL,
135146
NULL,
147+
NULL,
148+
NULL,
136149
};
137150

138151
const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_IO_FileSystem =
139152
{
140153
"System.IO.FileSystem",
141-
0x545A6C79,
154+
0x62EBC911,
142155
method_lookup,
143-
{ 1, 0, 0, 2 }
156+
{ 1, 1, 0, 0 }
144157
};
145158

146159
// clang-format on

src/System.IO.FileSystem/nf_sys_io_filesystem.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ typedef enum __nfpack StorageEventManager_StorageEventType
3838
StorageEventManager_StorageEventType_RemovableDeviceRemoval = 2,
3939
} StorageEventManager_StorageEventType;
4040

41+
typedef enum __nfpack DriveType
42+
{
43+
DriveType_Unknown = 0,
44+
DriveType_NoRootDirectory = 1,
45+
DriveType_Removable = 2,
46+
DriveType_Fixed = 3,
47+
DriveType_Ram = 4,
48+
} DriveType;
49+
4150
typedef enum __nfpack FileAccess
4251
{
4352
FileAccess_Read = 1,
@@ -150,6 +159,19 @@ struct Library_nf_sys_io_filesystem_System_IO_Directory
150159
//--//
151160
};
152161

162+
struct Library_nf_sys_io_filesystem_System_IO_DriveInfo
163+
{
164+
static const int FIELD___driveType = 1;
165+
static const int FIELD___name = 2;
166+
static const int FIELD___totalSize = 3;
167+
168+
NANOCLR_NATIVE_DECLARE(DriveInfoNative___VOID__STRING);
169+
NANOCLR_NATIVE_DECLARE(Format___STATIC__VOID__STRING);
170+
NANOCLR_NATIVE_DECLARE(GetDrivesNative___STATIC__SZARRAY_SystemIODriveInfo);
171+
172+
//--//
173+
};
174+
153175
struct Library_nf_sys_io_filesystem_System_IO_FileStream
154176
{
155177
static const int FIELD___canRead = 1;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
#include <nf_sys_io_filesystem.h>
7+
8+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::DriveInfoNative___VOID__STRING(CLR_RT_StackFrame &stack)
9+
{
10+
NANOCLR_HEADER();
11+
12+
NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
13+
14+
NANOCLR_NOCLEANUP();
15+
}
16+
17+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::Format___STATIC__VOID__STRING(CLR_RT_StackFrame &stack)
18+
{
19+
NANOCLR_HEADER();
20+
21+
NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
22+
23+
NANOCLR_NOCLEANUP();
24+
}
25+
26+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::GetDrivesNative___STATIC__SZARRAY_SystemIODriveInfo(
27+
CLR_RT_StackFrame &stack)
28+
{
29+
NANOCLR_HEADER();
30+
31+
NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
32+
33+
NANOCLR_NOCLEANUP();
34+
}

targets/ESP32/_common/Target_Windows_Storage.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343

4444
static const char *TAG = "SDCard";
4545

46+
sdmmc_card_t *card;
47+
4648
//
4749
// Unmount SD card ( MMC/SDIO or SPI)
4850
//
@@ -52,6 +54,9 @@ bool Storage_UnMountSDCard()
5254
{
5355
return false;
5456
}
57+
58+
card = NULL;
59+
5560
return true;
5661
}
5762

@@ -120,7 +125,6 @@ bool Storage_MountMMC(bool bit1Mode, int driveIndex)
120125
.max_files = SDC_MAX_OPEN_FILES,
121126
.allocation_unit_size = 16 * 1024};
122127

123-
sdmmc_card_t *card;
124128
errCode = esp_vfs_fat_sdmmc_mount(mountPoint, &host, &slot_config, &mount_config, &card);
125129
if (errCode == ESP_ERR_INVALID_STATE)
126130
{
@@ -166,8 +170,6 @@ bool Storage_MountSpi(int spiBus, uint32_t csPin, int driveIndex)
166170
.max_files = 5,
167171
.allocation_unit_size = 16 * 1024};
168172

169-
sdmmc_card_t *card;
170-
171173
// This initializes the slot without card detect (CD) and write protect (WP) signals.
172174
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
173175
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();

targets/ESP32/_nanoCLR/System.IO.FileSystem/nf_sys_io_filesystem_System_IO_Directory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ HRESULT Library_nf_sys_io_filesystem_System_IO_Directory::GetDirectoriesNative__
394394
// Enumerate drives in system
395395
// if array == null then only count drives
396396
// Return number of drives
397+
// TO BE REMOVED AFTER managed Directory.GetLogicalDrives() is removed
397398
static HRESULT EnumerateDrives(CLR_RT_HeapBlock *array, int &count)
398399
{
399400
NANOCLR_HEADER();
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
#include <nf_sys_io_filesystem.h>
7+
#include <esp_vfs_fat.h>
8+
#include <sdmmc_host.h>
9+
#include <diskio_impl.h>
10+
#include <targetHAL_FileOperation.h>
11+
#include <targetHAL_ConfigStorage.h>
12+
13+
typedef Library_nf_sys_io_filesystem_System_IO_DriveInfo DriveInfo;
14+
static HRESULT EnumerateDrives(CLR_RT_HeapBlock *array, int &count);
15+
16+
extern bool IsInternalFilePath(const char *filePath);
17+
extern "C" sdmmc_card_t *card;
18+
19+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::DriveInfoNative___VOID__STRING(CLR_RT_StackFrame &stack)
20+
{
21+
NANOCLR_HEADER();
22+
23+
char workingDrive[DRIVE_LETTER_LENGTH];
24+
25+
#if (HAL_USE_SDC == TRUE)
26+
char *vfsPath = NULL;
27+
int operationResult;
28+
struct stat fno;
29+
#endif
30+
31+
CLR_RT_TypeDef_Index driveInfoTypeDef;
32+
CLR_RT_HeapBlock *driveInfo;
33+
34+
CLR_RT_HeapBlock &top = stack.PushValue();
35+
36+
const char *drivePath = stack.Arg1().RecoverString();
37+
FAULT_ON_NULL_ARG(drivePath);
38+
39+
// copy the first 2 letters of the path for the drive
40+
// path is 'D:\folder\file.txt', so we need 'D:'
41+
memcpy(workingDrive, drivePath, DRIVE_LETTER_LENGTH);
42+
43+
// start composing the reply
44+
// find <DriveInfo> type definition, don't bother checking the result as it exists for sure
45+
g_CLR_RT_TypeSystem.FindTypeDef("DriveInfo", "System.IO", driveInfoTypeDef);
46+
47+
// create an instance of <DriveInfo>
48+
NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, driveInfoTypeDef));
49+
50+
// get a pointer to DriveInfo
51+
driveInfo = (CLR_RT_HeapBlock *)top.Dereference();
52+
53+
if (IsInternalFilePath(workingDrive))
54+
{
55+
// get the drive info from SPIFFs
56+
size_t total = 0, used = 0;
57+
esp_spiffs_info(SPIFFS_PARTITION_LABEL, &total, &used);
58+
59+
// fill in the drive info namaged fields
60+
driveInfo[FIELD___driveType].SetInteger(DriveType_Fixed);
61+
CLR_RT_HeapBlock_String::CreateInstance(driveInfo[FIELD___name], drivePath);
62+
driveInfo[FIELD___totalSize].SetInteger((CLR_UINT32)total);
63+
}
64+
else
65+
66+
#if (HAL_USE_SDC == TRUE)
67+
68+
{
69+
// assume "0:"" as we're always mounting 1 FATFS drive
70+
71+
operationResult = stat(vfsPath, &fno);
72+
if (operationResult == 0)
73+
{
74+
// fill in the drive info namaged fields
75+
driveInfo[FIELD___driveType].SetInteger(DriveType_Removable);
76+
CLR_RT_HeapBlock_String::CreateInstance(driveInfo[FIELD___name], drivePath);
77+
driveInfo[FIELD___totalSize].SetInteger((CLR_UINT32)fno.st_size);
78+
}
79+
else
80+
{
81+
// failed to get drive info
82+
NANOCLR_SET_AND_LEAVE(CLR_E_FILE_IO);
83+
}
84+
}
85+
86+
#endif // HAL_USE_SDC
87+
88+
{
89+
// unsupported drive
90+
NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
91+
}
92+
93+
NANOCLR_NOCLEANUP();
94+
}
95+
96+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::Format___STATIC__VOID__STRING(CLR_RT_StackFrame &stack)
97+
{
98+
NANOCLR_HEADER();
99+
100+
const char *drivePath = stack.Arg1().RecoverString();
101+
FAULT_ON_NULL_ARG(drivePath);
102+
103+
#if (HAL_USE_SDC == TRUE)
104+
105+
// check if SD card is mounted
106+
if (card != NULL)
107+
{
108+
// format it
109+
const size_t workbuf_size = 4096;
110+
111+
void *workbuf = NULL;
112+
BYTE pdrv;
113+
DWORD plist[] = {100, 0, 0, 0};
114+
115+
workbuf = ff_memalloc(workbuf_size);
116+
if (workbuf == NULL)
117+
{
118+
return ESP_ERR_NO_MEM;
119+
}
120+
121+
ff_diskio_get_drive(&pdrv);
122+
123+
f_fdisk(pdrv, plist, workbuf);
124+
}
125+
else
126+
{
127+
// SD card is not mounted
128+
// return error
129+
NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
130+
}
131+
#endif // HAL_USE_SDC
132+
133+
NANOCLR_NOCLEANUP();
134+
}
135+
136+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::GetDrivesNative___STATIC__SZARRAY_SystemIODriveInfo(
137+
CLR_RT_StackFrame &stack)
138+
{
139+
NANOCLR_HEADER();
140+
141+
int count = 0;
142+
143+
CLR_RT_HeapBlock &top = stack.PushValueAndClear();
144+
145+
// 1st pass find number of drives
146+
NANOCLR_CHECK_HRESULT(EnumerateDrives(NULL, count));
147+
148+
// create an array of files paths <String> for count drives
149+
NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(top, count, g_CLR_RT_WellKnownTypes.m_String));
150+
151+
// 2nd pass fill array with drives
152+
NANOCLR_CHECK_HRESULT(EnumerateDrives(&top, count));
153+
154+
NANOCLR_NOCLEANUP();
155+
}
156+
157+
// Enumerate drives in system
158+
// if array == null then only count drives
159+
// Return number of drives
160+
static HRESULT EnumerateDrives(CLR_RT_HeapBlock *array, int &count)
161+
{
162+
NANOCLR_HEADER();
163+
{
164+
CLR_RT_HeapBlock *storageFolder = NULL;
165+
DIR *currentDirectory;
166+
char outputDrive[] = INDEX0_DRIVE_PATH;
167+
char workingDrive[] = "/D/";
168+
169+
if (array)
170+
{
171+
// get a pointer to the first object in the array (which is of type <String>)
172+
storageFolder = (CLR_RT_HeapBlock *)array->DereferenceArray()->GetFirstElement();
173+
}
174+
175+
count = 0;
176+
for (char drive = INDEX0_DRIVE_LETTER[0]; drive <= INTERNAL_DRIVE0_LETTER[0]; drive++)
177+
{
178+
workingDrive[1] = drive;
179+
currentDirectory = opendir(workingDrive);
180+
if (currentDirectory != NULL)
181+
{
182+
count++;
183+
closedir(currentDirectory);
184+
185+
if (array)
186+
{
187+
// Add entry to array
188+
outputDrive[0] = drive;
189+
190+
// set the drive letter in string array
191+
NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance(*storageFolder, outputDrive));
192+
193+
// Next element in array
194+
storageFolder++;
195+
}
196+
}
197+
}
198+
}
199+
NANOCLR_NOCLEANUP();
200+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
#include <nf_sys_io_filesystem.h>
7+
8+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::DriveInfoNative___VOID__STRING(CLR_RT_StackFrame &stack)
9+
{
10+
NANOCLR_HEADER();
11+
12+
NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
13+
14+
NANOCLR_NOCLEANUP();
15+
}
16+
17+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::Format___STATIC__VOID__STRING(CLR_RT_StackFrame &stack)
18+
{
19+
NANOCLR_HEADER();
20+
21+
NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
22+
23+
NANOCLR_NOCLEANUP();
24+
}
25+
26+
HRESULT Library_nf_sys_io_filesystem_System_IO_DriveInfo::GetDrivesNative___STATIC__SZARRAY_SystemIODriveInfo(
27+
CLR_RT_StackFrame &stack)
28+
{
29+
NANOCLR_HEADER();
30+
31+
NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
32+
33+
NANOCLR_NOCLEANUP();
34+
}

0 commit comments

Comments
 (0)