author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Sat, 20 Feb 2010 00:10:51 +0200 | |
branch | RCL_3 |
changeset 19 | 4a8fed1c0ef6 |
parent 0 | a41df078684a |
permissions | -rw-r--r-- |
0 | 1 |
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
2 |
// All rights reserved. |
|
3 |
// This component and the accompanying materials are made available |
|
4 |
// under the terms of the License "Eclipse Public License v1.0" |
|
5 |
// which accompanies this distribution, and is available |
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 |
// |
|
8 |
// Initial Contributors: |
|
9 |
// Nokia Corporation - initial contribution. |
|
10 |
// |
|
11 |
// Contributors: |
|
12 |
// |
|
13 |
// Description: |
|
14 |
// Component test of registration and deregistration |
|
15 |
// 1. Test registering MS FS |
|
16 |
// Test actions: |
|
17 |
// a. Load MS Server/File system and start it. |
|
18 |
// b. Select a drive, say, Y, format it using FAT FS |
|
19 |
// c. Read and store the boot sector of Y |
|
20 |
// d. Unmount FAT FS from Y |
|
21 |
// e. Mount MS FS on Y |
|
22 |
// f. Read the boot sector of Y by passing SCSI command through TestLdd |
|
23 |
// g. Compare the two boot sectors, which are obtained under FAT MS and MS FS repectively |
|
24 |
// h. Try to read Y (assuming it's a removable media) using RFs API. |
|
25 |
// Expected results: |
|
26 |
// This test should be run for different drives. |
|
27 |
// Mounting non-removable media (step b) should fail. |
|
28 |
// For removable media: steps from c to g should complete successfully |
|
29 |
// Read boot sector should be the same as the saved. |
|
30 |
// Step h should fail (KErrNotSupported). |
|
31 |
// 2. Test deregistering MS FS |
|
32 |
// Test actions: |
|
33 |
// a. Try to unmount MS FS from Y while SCSI is writing to it |
|
34 |
// b. Wait for access completion. |
|
35 |
// c. Unmount MS FS from Y. |
|
36 |
// d. Try to read from Y using RFs API. |
|
37 |
// e. Remount FAT FS on Y. |
|
38 |
// f. Issue UnitReady and Read SCSI command through test LDD. |
|
39 |
// g. Try to read from Y using RFs API. |
|
40 |
// h. Unmount FAT FS from Y and mount MS FS on it |
|
41 |
// Expected results: |
|
42 |
// Deregister request (step a) should return an appropriate error code when media is in use. |
|
43 |
// Next deregistering (step c) should be successful. |
|
44 |
// Attempt (step d) should fail. |
|
45 |
// SCSI commands (step f) should report error when MS FS is unmounted. |
|
46 |
// File server read request (step g) should be successful when FAT FS is mounted |
|
47 |
// |
|
48 |
// |
|
49 |
||
50 |
/** |
|
51 |
@file |
|
52 |
@internalTechnology |
|
53 |
*/ |
|
54 |
||
55 |
#include <f32file.h> |
|
56 |
#include <e32test.h> |
|
57 |
#include <e32std.h> |
|
58 |
#include <e32std_private.h> |
|
59 |
#include <e32svr.h> |
|
60 |
#include <hal.h> |
|
61 |
#include <massstorage.h> |
|
62 |
#include "t_ms_main.h" |
|
63 |
#include "testusbc.h" |
|
64 |
||
65 |
#define CBW_LENGTH 31 |
|
66 |
#define CSW_LENGTH 13 |
|
67 |
#define SCSI_READ_LEN 10 |
|
68 |
#define SCSI_WRITE_LEN 10 |
|
69 |
#define SCSI_UNIT_READY_LEN 6 |
|
70 |
#define SCSI_MED_RMVL_LEN 6 |
|
71 |
#define BOOTSECTOR_SIZE 512 |
|
72 |
||
73 |
_LIT(KMsFsyName, "MassStorageFileSystem"); |
|
74 |
||
75 |
const TUint KMBRFirstPartitionSectorOffset = 0x1BE + 8; |
|
76 |
const TUint KBootRecordSignature = 0xAA55; |
|
77 |
||
78 |
LOCAL_D TChar driveLetter[2]; |
|
79 |
LOCAL_D TInt nonRemovalDrvNo; |
|
80 |
LOCAL_D TInt removalDrvNo; |
|
81 |
LOCAL_D TUint8 testLun(0); // Use MMC card for testing |
|
82 |
||
83 |
#define LOG_AND_TEST(a, e) {if (a!=e) {test.Printf(_L("lvalue %d, rvalue%d\n\r"), a,e); test(EFalse);}} |
|
84 |
LOCAL_C void ParseCommandArguments() |
|
85 |
// |
|
86 |
// Parses the command line arguments |
|
87 |
// We expect 3 parameters: |
|
88 |
// - Drive letter for non-removable drive |
|
89 |
// - Drive letter for removable drive |
|
90 |
// - LUN for removable drive (0-7) |
|
91 |
// |
|
92 |
{ |
|
93 |
TBuf<0x100> cmd; |
|
94 |
User::CommandLine(cmd); |
|
95 |
TLex lex(cmd); |
|
96 |
TPtrC token; |
|
97 |
TBool cmdOk= ETrue; |
|
98 |
for (int i = 0; i < 3; i++) // |
|
99 |
{ |
|
100 |
token.Set(lex.NextToken()); |
|
101 |
if (token.Length() != 0) |
|
102 |
{ |
|
103 |
if (i <2) |
|
104 |
{ |
|
105 |
driveLetter[i] = token[0]; |
|
106 |
driveLetter[i].UpperCase(); |
|
107 |
test.Printf(_L("CmdLine Param=%S\r\n"),&token); |
|
108 |
} |
|
109 |
else |
|
110 |
{ |
|
111 |
TChar cLun = token[0]; |
|
112 |
TInt lun = TInt(cLun) - 0x30; |
|
113 |
if (lun>=0 && lun <8) |
|
114 |
{ |
|
115 |
testLun = TUint8(lun); |
|
116 |
} |
|
117 |
else |
|
118 |
{ |
|
119 |
cmdOk= EFalse; |
|
120 |
} |
|
121 |
} |
|
122 |
} |
|
123 |
else |
|
124 |
{ |
|
125 |
cmdOk= EFalse; |
|
126 |
break; |
|
127 |
} |
|
128 |
} |
|
129 |
||
130 |
||
131 |
if (!cmdOk) |
|
132 |
{ |
|
133 |
test.Printf(_L("No or not enough command line arguments - using default arguments\r\n")); |
|
134 |
// code drive letters based on platform |
|
135 |
TInt uid; |
|
136 |
TInt r=HAL::Get(HAL::EMachineUid,uid); |
|
137 |
LOG_AND_TEST(r,KErrNone); |
|
138 |
||
139 |
switch(uid) |
|
140 |
{ |
|
141 |
case HAL::EMachineUid_Lubbock: |
|
142 |
driveLetter[0] = 'C'; |
|
143 |
driveLetter[1] = 'F'; |
|
144 |
test.Printf(_L("Test is running on Lubbock\r\n")); |
|
145 |
testLun = 2; |
|
146 |
break; |
|
147 |
case HAL::EMachineUid_Win32Emulator: |
|
148 |
driveLetter[0] = 'Y'; |
|
149 |
driveLetter[1] = 'X'; |
|
150 |
test.Printf(_L("Test is running on Win32 Emulator\r\n")); |
|
151 |
testLun = 1; |
|
152 |
break; |
|
153 |
case HAL::EMachineUid_OmapH4: |
|
154 |
driveLetter[0] = 'C'; |
|
155 |
driveLetter[1] = 'D'; |
|
156 |
test.Printf(_L("Test is running on H4 board\r\n")); |
|
157 |
testLun = 0; |
|
158 |
break; |
|
159 |
default: |
|
160 |
// Assume it's a H2 board for now as no relevant Enum is found |
|
161 |
driveLetter[0] = 'C'; |
|
162 |
driveLetter[1] = 'D'; |
|
163 |
test.Printf(_L("Test is running on H2 board\r\n")); |
|
164 |
testLun = 0; |
|
165 |
break; |
|
166 |
} |
|
167 |
||
168 |
test.Printf(_L("Parameters used for test:\r\n\tfixed drive\t\t%c\r\n\tremovable drive\t\t%c\r\n\tLUN\t\t\t%d\r\n"), |
|
169 |
(TUint) driveLetter[0], (TUint) driveLetter[1], testLun); |
|
170 |
} |
|
171 |
} |
|
172 |
||
173 |
LOCAL_C void fillInt(TUint8* dest, TInt source) |
|
174 |
// |
|
175 |
// Copy an int. Little endian |
|
176 |
// |
|
177 |
{ |
|
178 |
for (TInt i = 0; i < 4; i++) |
|
179 |
{ |
|
180 |
*dest++ = TUint8((source >> i*8) & 0xFF); |
|
181 |
} |
|
182 |
} |
|
183 |
||
184 |
LOCAL_C TInt extractInt(const TUint8* aBuf) |
|
185 |
// |
|
186 |
// Extract an integer from a buffer. Assume little endian |
|
187 |
// |
|
188 |
{ |
|
189 |
return aBuf[0] + (aBuf[1] << 8) + (aBuf[2] << 16) + (aBuf[3] << 24); |
|
190 |
} |
|
191 |
||
192 |
LOCAL_C void createReadCmd(TDes8& aRead10Buf, TInt aLogicalBlkAddr, TInt aTotalBlocks) |
|
193 |
// |
|
194 |
// Prepare SCSI read(10) command |
|
195 |
// |
|
196 |
{ |
|
197 |
// Zero out the whole buffer |
|
198 |
aRead10Buf.FillZ(SCSI_READ_LEN); |
|
199 |
// operation code |
|
200 |
aRead10Buf[0] = 0x28; |
|
201 |
// Fill in logical block address. Big endian |
|
202 |
aRead10Buf[2] = TUint8((aLogicalBlkAddr >> 24) & 0xFF); |
|
203 |
aRead10Buf[3] = TUint8((aLogicalBlkAddr >> 16) & 0xFF); |
|
204 |
aRead10Buf[4] = TUint8((aLogicalBlkAddr >> 8) & 0xFF); |
|
205 |
aRead10Buf[5] = TUint8(aLogicalBlkAddr & 0xFF); |
|
206 |
||
207 |
// Data transfer length (# of sectors). Big endian |
|
208 |
aRead10Buf[7] = TUint8((aTotalBlocks >> 8) & 0xFF); |
|
209 |
aRead10Buf[8] = TUint8((aTotalBlocks & 0xFF)); |
|
210 |
} |
|
211 |
||
212 |
LOCAL_C void createCBW(TDes8& aCbw, TInt aDCBWTag, TInt aDataTransferLen, TUint8 aInOutFlag, TUint8 aCBLength, TDes8& aCBWCB) |
|
213 |
// |
|
214 |
// aCbw: stores CBW |
|
215 |
// aDCBWTag: a command block tag sent by the host. Used to associates a CSW |
|
216 |
// with corresponding CBW |
|
217 |
// aDataTranferLen: the number of bytes the host expects to transfer |
|
218 |
// aInOutFlag: value for bmCBWFlags field, indicating the direction of transfer |
|
219 |
// aCBLengh: valid length of CBWCB field in bytes |
|
220 |
// aCBWCB the actual command to be wrapped |
|
221 |
{ |
|
222 |
// Zero out aCbw |
|
223 |
aCbw.FillZ(CBW_LENGTH); |
|
224 |
||
225 |
// dCBWSignature field, the value comes from spec |
|
226 |
TInt dCBWSignature = 0x43425355; |
|
227 |
fillInt(&aCbw[0], dCBWSignature); |
|
228 |
// dCBWTag field |
|
229 |
fillInt(&aCbw[4], aDCBWTag); |
|
230 |
// dCBWDataTransferLength field |
|
231 |
fillInt(&aCbw[8], aDataTransferLen); |
|
232 |
// bmCBWFlags field |
|
233 |
aCbw[12] = aInOutFlag; |
|
234 |
aCbw[13] = testLun; |
|
235 |
// bCBWCBLength field |
|
236 |
aCbw[14] = aCBLength; |
|
237 |
||
238 |
// CBWCB field |
|
239 |
for (TInt i = 0; i < aCBLength; ++i) |
|
240 |
{ |
|
241 |
aCbw[15 + i] = aCBWCB[i]; |
|
242 |
} |
|
243 |
} |
|
244 |
||
245 |
LOCAL_C void doComponentTest() |
|
246 |
// |
|
247 |
// Do the component test |
|
248 |
// |
|
249 |
{ |
|
250 |
__UHEAP_MARK; |
|
251 |
||
252 |
TInt ret; |
|
253 |
test.Next(_L("Start MountStart test. Be sure MMC card is inserted.")); |
|
254 |
||
255 |
// Connect to the server |
|
256 |
RFs fs; |
|
257 |
LOG_AND_TEST(KErrNone, fs.Connect()); |
|
258 |
||
259 |
// Convert drive letters to their numerical equivalent |
|
260 |
ret = fs.CharToDrive(driveLetter[0],nonRemovalDrvNo); |
|
261 |
LOG_AND_TEST(ret, KErrNone); |
|
262 |
ret = fs.CharToDrive(driveLetter[1],removalDrvNo); |
|
263 |
LOG_AND_TEST(ret, KErrNone); |
|
264 |
||
265 |
||
266 |
// Load the logical device |
|
267 |
_LIT(KDriverFileName,"TESTUSBC.LDD"); |
|
268 |
ret = User::LoadLogicalDevice(KDriverFileName); |
|
269 |
test(ret == KErrNone || ret == KErrAlreadyExists); |
|
270 |
||
271 |
// Add MS file system |
|
272 |
_LIT(KMsFs, "MSFS.FSY"); |
|
273 |
ret = fs.AddFileSystem(KMsFs); |
|
274 |
test(ret == KErrNone || ret == KErrAlreadyExists); |
|
275 |
||
276 |
// DEF080979: RFs::AddFileSystem, wrong error code when re-adding |
|
277 |
// the mass storage file system. Confirm that RFs::AddFileSystem |
|
278 |
// returns the correct error code if the file system already exists. |
|
279 |
// Also confirm that the mass storage file system is usable after such |
|
280 |
// a failed attempt to re-add the file system. |
|
281 |
ret = fs.AddFileSystem(KMsFs); |
|
282 |
test(ret == KErrAlreadyExists); |
|
283 |
||
284 |
// Start Ms file system |
|
285 |
RUsbMassStorage usbMs; |
|
286 |
||
287 |
TMassStorageConfig config; |
|
288 |
||
289 |
config.iVendorId.Copy(_L("vendorId")); |
|
290 |
config.iProductId.Copy(_L("productId")); |
|
291 |
config.iProductRev.Copy(_L("rev")); |
|
292 |
||
293 |
||
294 |
ret = usbMs.Connect(); |
|
295 |
LOG_AND_TEST(KErrNone, ret); |
|
296 |
||
297 |
// Start usb mass storage device |
|
298 |
LOG_AND_TEST(KErrNone , usbMs.Start(config)); |
|
299 |
||
300 |
TBuf<128> fsName; |
|
301 |
||
302 |
#if defined(__WINS__) //we have no "free" non-removable drive at hardware to run this, |
|
303 |
||
304 |
// Get the file system name on non-removable drive |
|
305 |
||
306 |
LOG_AND_TEST(KErrNone ,fs.FileSystemName(fsName, nonRemovalDrvNo)); |
|
307 |
||
308 |
// Mount MS FS on to non-removable drive. This should fail |
|
309 |
test(KErrNone != fs.MountFileSystem(KMsFsyName, nonRemovalDrvNo)); |
|
310 |
||
311 |
// Unmount MS FS from non-removable drive |
|
312 |
LOG_AND_TEST(KErrNone, fs.DismountFileSystem(KMsFsyName, nonRemovalDrvNo)); |
|
313 |
||
314 |
// Mount FAT FS on to drive (restoring) |
|
315 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, nonRemovalDrvNo)); |
|
316 |
#endif //WINS |
|
317 |
||
318 |
// Format removable drive using FAT FS |
|
319 |
RFormat format; |
|
320 |
||
321 |
TBuf<2> removalDrive; |
|
322 |
removalDrive.Append(driveLetter[1]); |
|
323 |
removalDrive.Append(':'); |
|
324 |
TInt tracksRemaining; |
|
325 |
test.Next(_L("Start MMC card formatting")); |
|
326 |
LOG_AND_TEST(KErrNone, format.Open(fs, removalDrive, EHighDensity || EQuickFormat, tracksRemaining)); |
|
327 |
while (tracksRemaining) |
|
328 |
{ |
|
329 |
test.Printf(_L(".")); |
|
330 |
LOG_AND_TEST(KErrNone, format.Next(tracksRemaining)); |
|
331 |
} |
|
332 |
format.Close(); |
|
333 |
test.Printf(_L("\nDone!\n")); |
|
334 |
// Get the boot sector info using FAT FS and save it for later comparison |
|
335 |
TBuf8<512> fatBootSector; |
|
336 |
RRawDisk fatDiskF; |
|
337 |
LOG_AND_TEST(KErrNone, fatDiskF.Open(fs, removalDrvNo)); |
|
338 |
LOG_AND_TEST(KErrNone, fatDiskF.Read(0, fatBootSector)); |
|
339 |
fatDiskF.Close(); |
|
340 |
||
341 |
LOG_AND_TEST(KErrNone, fs.FileSystemName(fsName, removalDrvNo)); |
|
342 |
||
343 |
// Set up sessions for dismount API tests |
|
344 |
||
345 |
const TInt KNumClients = 10; |
|
346 |
RFs clientFs[KNumClients]; |
|
347 |
RFs dismountFs1; |
|
348 |
TRequestStatus trsClientNotify[KNumClients]; |
|
349 |
TRequestStatus trsClientComplete; |
|
350 |
TRequestStatus trsClientComplete1; |
|
351 |
||
352 |
LOG_AND_TEST(KErrNone, dismountFs1.Connect()); |
|
353 |
||
354 |
TInt i = 0; |
|
355 |
for(i=0; i< KNumClients; i++) |
|
356 |
{ |
|
357 |
LOG_AND_TEST(KErrNone, clientFs[i].Connect()); |
|
358 |
} |
|
359 |
||
360 |
// Test invalid mode argument to RFs::NotifyDismount |
|
361 |
||
362 |
test.Next(_L("Test invalid mode argument to RFs::NotifyDismount")); |
|
363 |
for(i=0; i< KNumClients; i++) |
|
364 |
{ |
|
365 |
clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i], (TNotifyDismountMode)0xFEEDFACE); |
|
366 |
test(trsClientNotify[i] == KErrArgument); |
|
367 |
} |
|
368 |
||
369 |
// Register for notification of pending media removal and check status |
|
370 |
||
371 |
test.Next(_L("Register for notification of pending media removal and check status")); |
|
372 |
for(i=0; i< KNumClients; i++) |
|
373 |
{ |
|
374 |
clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); |
|
375 |
test(trsClientNotify[i] == KRequestPending); |
|
376 |
} |
|
377 |
||
378 |
// Notify clients of pending media removal and check status |
|
379 |
||
380 |
test.Next(_L("Notify clients of pending media removal and check status")); |
|
381 |
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); |
|
382 |
test(trsClientComplete == KRequestPending); |
|
383 |
||
384 |
// Check that client has notification of pending media removal |
|
385 |
||
386 |
test.Next(_L("Check that client has notification of pending media removal")); |
|
387 |
for(i=0; i< KNumClients; i++) |
|
388 |
{ |
|
389 |
test(trsClientNotify[i] == KErrNone); |
|
390 |
} |
|
391 |
||
392 |
// Respond to the dismount using RFs::AllowDismount (only 2 clients) |
|
393 |
||
394 |
LOG_AND_TEST(KErrNone, clientFs[0].AllowDismount(removalDrvNo)); |
|
395 |
test(trsClientComplete == KRequestPending); |
|
396 |
LOG_AND_TEST(KErrNone, clientFs[1].AllowDismount(removalDrvNo)); |
|
397 |
test(trsClientComplete == KRequestPending); |
|
398 |
||
399 |
// Check that file system can't be dismounted as all clients haven't responded |
|
400 |
||
401 |
test.Next(_L("Check that file system can't be dismounted as all clients haven't responded")); |
|
402 |
LOG_AND_TEST(KErrInUse, fs.DismountFileSystem(fsName, removalDrvNo)); |
|
403 |
||
404 |
// Before all clients have completed, cancel the dismount |
|
405 |
||
406 |
test.Next(_L("Before all clients have completed, cancel the dismount")); |
|
407 |
fs.NotifyDismountCancel(trsClientComplete); |
|
408 |
test(trsClientComplete == KErrCancel); |
|
409 |
||
410 |
for(i=2; i< KNumClients; i++) |
|
411 |
{ |
|
412 |
LOG_AND_TEST(KErrNone, clientFs[i].AllowDismount(removalDrvNo)); |
|
413 |
LOG_AND_TEST(KErrNotFound, clientFs[i].AllowDismount(removalDrvNo)); |
|
414 |
test(trsClientComplete == KErrCancel); |
|
415 |
} |
|
416 |
||
417 |
// Check that file system can be dismounted after cancelling async dismount |
|
418 |
||
419 |
test.Next(_L("Check that file system can be dismounted after cancelling async dismount")); |
|
420 |
LOG_AND_TEST(KErrNone, fs.DismountFileSystem(fsName, removalDrvNo)); |
|
421 |
||
422 |
// ...remount FAT |
|
423 |
||
424 |
test.Next(_L("Mount FAT FS on to the removal drive")); |
|
425 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); |
|
426 |
||
427 |
for(i=0; i< KNumClients; i++) |
|
428 |
clientFs[i].Close(); |
|
429 |
||
430 |
dismountFs1.Close(); |
|
431 |
||
432 |
// |
|
433 |
// Test dismounting while resourses are open |
|
434 |
// |
|
435 |
||
436 |
_LIT(KFileName, ":\\foo"); |
|
437 |
TBuf<7> fileName; |
|
438 |
fileName.Append(driveLetter[1]); |
|
439 |
fileName.Append(KFileName); |
|
440 |
||
441 |
RFile file; |
|
442 |
test.Next(_L("Attempting to open a file\n\r")); |
|
443 |
ret = file.Create(fs, fileName, EFileRead | EFileReadDirectIO | EFileWriteDirectIO); |
|
444 |
test(ret == KErrNone || ret == KErrAlreadyExists); |
|
445 |
LOG_AND_TEST(KErrNone, file.Write(0,_L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"))); |
|
446 |
file.Close(); |
|
447 |
||
448 |
TBuf<7> dirName; |
|
449 |
dirName.Append(driveLetter[1]); |
|
450 |
dirName.Append(KFileName); |
|
451 |
||
452 |
RDir dir; |
|
453 |
TEntry dirEntry; |
|
454 |
test.Next(_L("Attempting to open a directory\n\r")); |
|
455 |
LOG_AND_TEST(KErrNone, dir.Open(fs, dirName, KEntryAttNormal)); |
|
456 |
LOG_AND_TEST(KErrNone, dir.Read(dirEntry)); |
|
457 |
dir.Close(); |
|
458 |
||
459 |
fs.Close(); |
|
460 |
||
461 |
TInt pass; |
|
462 |
for(pass=0; pass<5; pass++) |
|
463 |
{ |
|
464 |
LOG_AND_TEST(KErrNone, fs.Connect()); |
|
465 |
LOG_AND_TEST(KErrNone, dismountFs1.Connect()); |
|
466 |
||
467 |
TInt i = 0; |
|
468 |
for(i=0; i< KNumClients; i++) |
|
469 |
{ |
|
470 |
LOG_AND_TEST(KErrNone, clientFs[i].Connect()); |
|
471 |
} |
|
472 |
||
473 |
// Open a file on the removable drive |
|
474 |
||
475 |
RFile file; |
|
476 |
LOG_AND_TEST(KErrNone, file.Open(fs, fileName, EFileRead | EFileReadDirectIO | EFileWriteDirectIO)); |
|
477 |
TBuf8<0x40> buf1; |
|
478 |
LOG_AND_TEST(KErrNone, file.Read(0, buf1)); |
|
479 |
LOG_AND_TEST(36, buf1.Length()); |
|
480 |
test(buf1 == _L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); |
|
481 |
||
482 |
// Unmount FAT FS from the removable drive - this should fail with a file open |
|
483 |
||
484 |
LOG_AND_TEST(KErrInUse, fs.DismountFileSystem(fsName, removalDrvNo)); |
|
485 |
||
486 |
// Open a directory on the removable drive |
|
487 |
||
488 |
test.Next(_L("Attempting to open a directory\n\r")); |
|
489 |
LOG_AND_TEST(KErrNone, dir.Open(fs, dirName, KEntryAttNormal)); |
|
490 |
LOG_AND_TEST(KErrNone, dir.Read(dirEntry)); |
|
491 |
||
492 |
// Check simple client dismount notification and cancel (before issuing a dismount request) |
|
493 |
||
494 |
test.Next(_L("Register for notification of pending media removal and check status")); |
|
495 |
for(i=0; i< KNumClients; i++) |
|
496 |
{ |
|
497 |
clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); |
|
498 |
test(trsClientNotify[i] == KRequestPending); |
|
499 |
} |
|
500 |
||
501 |
test.Next(_L("Cancel notification of pending media removal and check status")); |
|
502 |
for(i=0; i< KNumClients; i++) |
|
503 |
{ |
|
504 |
clientFs[i].NotifyDismountCancel(trsClientNotify[i]); |
|
505 |
test(trsClientNotify[i] == KErrCancel); |
|
506 |
} |
|
507 |
||
508 |
// Check issuing and cancelling a dismount request while clients are responding |
|
509 |
||
510 |
test.Next(_L("Register for notification of pending media removal (again) and check status")); |
|
511 |
for(i=0; i< KNumClients; i++) |
|
512 |
{ |
|
513 |
clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); |
|
514 |
test(trsClientNotify[i] == KRequestPending); |
|
515 |
} |
|
516 |
||
517 |
test.Next(_L("Notify clients of pending media removal and check status")); |
|
518 |
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); |
|
519 |
test(trsClientComplete == KRequestPending); |
|
520 |
||
521 |
test.Next(_L("Check that client has notification of pending media removal")); |
|
522 |
for(i=0; i< KNumClients; i++) |
|
523 |
{ |
|
524 |
test(trsClientNotify[i] == KErrNone); |
|
525 |
} |
|
526 |
||
527 |
LOG_AND_TEST(KErrNone, clientFs[0].AllowDismount(removalDrvNo)); |
|
528 |
test(trsClientComplete == KRequestPending); |
|
529 |
LOG_AND_TEST(KErrNone, clientFs[1].AllowDismount(removalDrvNo)); |
|
530 |
test(trsClientComplete == KRequestPending); |
|
531 |
test.Next(_L("Before all clients have completed, cancel the dismount")); |
|
532 |
fs.NotifyDismountCancel(trsClientComplete); |
|
533 |
test(trsClientComplete == KErrCancel); |
|
534 |
||
535 |
for(i=2; i< KNumClients; i++) |
|
536 |
{ |
|
537 |
LOG_AND_TEST(KErrNone, clientFs[i].AllowDismount(removalDrvNo)); |
|
538 |
test(trsClientComplete == KErrCancel); |
|
539 |
} |
|
540 |
||
541 |
// Check dismounting, responding, cancelling and forced remounting |
|
542 |
||
543 |
test.Next(_L("Register for notification of pending media removal (again) and check status")); |
|
544 |
for(i=0; i< KNumClients; i++) |
|
545 |
{ |
|
546 |
clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); |
|
547 |
test(trsClientNotify[i] == KRequestPending); |
|
548 |
} |
|
549 |
||
550 |
test.Next(_L("Notify clients of pending media removal and check status")); |
|
551 |
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); |
|
552 |
test(trsClientComplete == KRequestPending); |
|
553 |
||
554 |
test.Next(_L("Check that client has notification of pending media removal")); |
|
555 |
for(i=0; i< KNumClients; i++) |
|
556 |
{ |
|
557 |
test(trsClientNotify[i] == KErrNone); |
|
558 |
} |
|
559 |
||
560 |
test.Next(_L("Notify clients of pending media removal with another session and check status")); |
|
561 |
fs.NotifyDismount(removalDrvNo, trsClientComplete1, EFsDismountNotifyClients); |
|
562 |
test(trsClientComplete1 == KErrInUse); |
|
563 |
||
564 |
TInt expectedAllowDismountRet = KErrNone; |
|
565 |
TInt expectedCompletionCode = KRequestPending; |
|
566 |
if(pass & 0x01) |
|
567 |
{ |
|
568 |
test.Next(_L("No response from clients - Force a dismount")); |
|
569 |
test.Next(_L("...cancelling original request")); |
|
570 |
fs.NotifyDismountCancel(trsClientComplete); |
|
571 |
test(trsClientComplete == KErrCancel); |
|
572 |
test.Next(_L("...issuing a forced dismount request")); |
|
573 |
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountForceDismount); |
|
574 |
test(trsClientComplete == KErrNone); |
|
575 |
expectedAllowDismountRet = KErrNotReady; |
|
576 |
expectedCompletionCode = KErrNone; |
|
577 |
} |
|
578 |
||
579 |
test.Next(_L("Allow dismount and check response")); |
|
580 |
for(i=0; i < KNumClients; i++) |
|
581 |
{ |
|
582 |
LOG_AND_TEST(expectedAllowDismountRet, clientFs[i].AllowDismount(removalDrvNo)); |
|
583 |
if(i == KNumClients-1) |
|
584 |
test(trsClientComplete == KErrNone); |
|
585 |
else |
|
586 |
test(trsClientComplete == expectedCompletionCode); |
|
587 |
} |
|
588 |
||
589 |
// The last test should have dismounted the file system |
|
590 |
||
591 |
LOG_AND_TEST(KErrNotReady, file.Read(0,buf1)); |
|
592 |
LOG_AND_TEST(KErrNotReady, dir.Read(dirEntry)); |
|
593 |
||
594 |
test.Next(_L("FAT File System should now be dismounted from the drive")); |
|
595 |
LOG_AND_TEST(KErrNotReady, fs.DismountFileSystem(fsName, removalDrvNo)); |
|
596 |
||
597 |
test.Next(_L("Mount MS FS on to the removable drive")); |
|
598 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(KMsFsyName, removalDrvNo)); |
|
599 |
||
600 |
LOG_AND_TEST(KErrDisMounted, file.Read(0,buf1)); |
|
601 |
LOG_AND_TEST(KErrDisMounted, dir.Read(dirEntry)); |
|
602 |
||
603 |
test.Next(_L("Dismount MSFS normally")); |
|
604 |
LOG_AND_TEST(KErrNone, fs.DismountFileSystem(KMsFsyName, removalDrvNo)); |
|
605 |
||
606 |
test.Next(_L("Mount FAT FS on to the removal drive")); |
|
607 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); |
|
608 |
||
609 |
LOG_AND_TEST(KErrNone, file.Read(0,buf1)); |
|
610 |
LOG_AND_TEST(KErrEof, dir.Read(dirEntry)); // drive freshly formatted, so only root dir exists |
|
611 |
||
612 |
// Test multiple notifiers on a single session |
|
613 |
||
614 |
test.Next(_L("Register several notifiers for a single session and check status")); |
|
615 |
for(i=0; i< KNumClients; i++) |
|
616 |
{ |
|
617 |
clientFs[0].NotifyDismount(removalDrvNo, trsClientNotify[i]); |
|
618 |
test(trsClientNotify[i] == KRequestPending); |
|
619 |
} |
|
620 |
||
621 |
test.Next(_L("Notify clients and verify all requests signalled")); |
|
622 |
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); |
|
623 |
||
624 |
test.Next(_L("Allow dismount 3 times from same session")); |
|
625 |
for(i=0; i< KNumClients; i++) |
|
626 |
{ |
|
627 |
test(trsClientComplete == KRequestPending); |
|
628 |
test(trsClientNotify[i] == KErrNone); |
|
629 |
LOG_AND_TEST(KErrNone, clientFs[0].AllowDismount(removalDrvNo)); |
|
630 |
} |
|
631 |
||
632 |
test.Next(_L("Verify that file system has been dismounted")); |
|
633 |
test(trsClientComplete == KErrNone); |
|
634 |
||
635 |
test.Next(_L("Mount FAT FS on to the removal drive")); |
|
636 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); |
|
637 |
||
638 |
// Test multiple notifiers on different drives |
|
639 |
||
640 |
const TInt KNumDrives = 1; |
|
641 |
||
642 |
test.Next(_L("Register several notifiers for different drives and check status")); |
|
643 |
for(i=0; i < KNumDrives; i++) |
|
644 |
{ |
|
645 |
clientFs[0].NotifyDismount(removalDrvNo + i, trsClientNotify[i]); |
|
646 |
test(trsClientNotify[i] == KRequestPending); |
|
647 |
} |
|
648 |
||
649 |
test.Next(_L("Notify clients and verify all requests signalled")); |
|
650 |
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); |
|
651 |
test(trsClientComplete == KRequestPending); |
|
652 |
||
653 |
test(trsClientNotify[0] == KErrNone); |
|
654 |
LOG_AND_TEST(KErrNone, clientFs[0].AllowDismount(removalDrvNo)); |
|
655 |
for(i=1; i< KNumDrives; i++) |
|
656 |
{ |
|
657 |
test(trsClientNotify[i] == KRequestPending); |
|
658 |
} |
|
659 |
||
660 |
test.Next(_L("Verify that file system has been dismounted")); |
|
661 |
test(trsClientComplete == KErrNone); |
|
662 |
||
663 |
test.Next(_L("Check that file can be closed when filesystem is dismounted")); |
|
664 |
file.Close(); |
|
665 |
dir.Close(); |
|
666 |
||
667 |
test.Next(_L("Mount FAT FS on to the removal drive")); |
|
668 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); |
|
669 |
||
670 |
test.Next(_L("Cancel all outstanding notifiers for this session")); |
|
671 |
clientFs[0].NotifyDismountCancel(); |
|
672 |
for(i=1; i< KNumDrives; i++) |
|
673 |
{ |
|
674 |
test(trsClientNotify[i] == KErrCancel); |
|
675 |
} |
|
676 |
||
677 |
// Test session disconnect |
|
678 |
test.Next(_L("Register for notification of pending media removal (again) and check status")); |
|
679 |
for(i=0; i< KNumClients; i++) |
|
680 |
{ |
|
681 |
clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); |
|
682 |
test(trsClientNotify[i] == KRequestPending); |
|
683 |
} |
|
684 |
||
685 |
test.Next(_L("Close client sessions with outstanding notifiers")); |
|
686 |
for(i=0; i< KNumClients; i++) |
|
687 |
clientFs[i].Close(); |
|
688 |
||
689 |
// Since all clients have been closed, the next stage should result in a dismount |
|
690 |
test.Next(_L("Notify clients of pending media removal and check status")); |
|
691 |
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); |
|
692 |
test(trsClientComplete == KErrNone); |
|
693 |
||
694 |
test.Next(_L("Mount FAT FS on to the removal drive")); |
|
695 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); |
|
696 |
||
697 |
TRequestStatus trs1; |
|
698 |
dismountFs1.NotifyDismount(removalDrvNo, trs1); |
|
699 |
test(trs1 == KRequestPending); |
|
700 |
||
701 |
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); |
|
702 |
test(trsClientComplete == KRequestPending); |
|
703 |
||
19
4a8fed1c0ef6
Revision: 201007
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
704 |
fs.NotifyDismountCancel(trsClientComplete); |
4a8fed1c0ef6
Revision: 201007
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
705 |
|
0 | 706 |
fs.Close(); |
707 |
dismountFs1.Close(); |
|
708 |
} |
|
709 |
||
710 |
// Check that files/directories can't be opened on Mass Storage |
|
711 |
||
712 |
LOG_AND_TEST(KErrNone, fs.Connect()); |
|
713 |
||
714 |
test.Next(_L("Dismount FAT File System")); |
|
715 |
LOG_AND_TEST(KErrNone, fs.DismountFileSystem(fsName, removalDrvNo)); |
|
716 |
||
717 |
test.Next(_L("Mount MS FS on to the removable drive")); |
|
718 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(KMsFsyName, removalDrvNo)); |
|
719 |
||
720 |
test.Next(_L("Attempting to open a file\n\r")); |
|
721 |
LOG_AND_TEST(KErrNotReady, file.Open(fs, fileName, EFileRead)); |
|
722 |
||
723 |
test.Next(_L("Attempting to open a directory\n\r")); |
|
724 |
LOG_AND_TEST(KErrNotReady, dir.Open(fs, fileName, KEntryAttNormal)); |
|
725 |
||
726 |
// Test fix for DEF058681 - Mass Storage reports VolumeName incorrectly. |
|
727 |
// Before the fix, CMassStorageMountCB::MountL() did not set the volume |
|
728 |
// name, resulting in a panic when attempting to copy a null descriptor. |
|
729 |
// Note that the volume name is still not returned client-side, since |
|
730 |
// CMassStorageMountCB::VolumeL() returns KErrNotReady |
|
731 |
TVolumeInfo volInfo; |
|
732 |
ret = fs.Volume(volInfo, removalDrvNo); |
|
733 |
LOG_AND_TEST(ret, KErrNotReady); |
|
734 |
LOG_AND_TEST(volInfo.iName.Length(), 0); |
|
735 |
||
736 |
// ------------------------------------------------- |
|
737 |
||
738 |
// Get the boot sector info using MS FS and save it for later comparison |
|
739 |
TBuf8<CBW_LENGTH> cbwBuf; |
|
740 |
TInt dCBWTag = 1234567; // arbitrary, any number would do for this test. |
|
741 |
||
742 |
RDevTestUsbcClient usbcClient; |
|
743 |
||
744 |
// Open a session to LDD |
|
745 |
test.Next(_L("Open LDD")); |
|
746 |
LOG_AND_TEST(KErrNone, usbcClient.Open(0)); |
|
747 |
||
748 |
// Build SCSI command test unit ready |
|
749 |
TBuf8<SCSI_UNIT_READY_LEN> unitReadyBuf; |
|
750 |
// Zero out the buf |
|
751 |
unitReadyBuf.FillZ(SCSI_UNIT_READY_LEN); |
|
752 |
||
753 |
createCBW(cbwBuf, dCBWTag, 0, 0, SCSI_UNIT_READY_LEN, unitReadyBuf); |
|
754 |
||
755 |
// Send test unit ready command |
|
756 |
test.Next(_L("Sending CBW with 'Unit Ready' cmd")); |
|
757 |
TRequestStatus status; |
|
758 |
usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); |
|
759 |
User::WaitForRequest(status); |
|
760 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
761 |
||
762 |
// Read CSW |
|
763 |
test.Next(_L("Reading CSW")); |
|
764 |
TBuf8<CSW_LENGTH> cswBuf; |
|
765 |
usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); |
|
766 |
User::WaitForRequest(status); |
|
767 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
768 |
||
769 |
// Check dCSWTag |
|
770 |
TInt recvedCBWTag = extractInt(&cswBuf[4]); |
|
771 |
LOG_AND_TEST(dCBWTag, recvedCBWTag); |
|
772 |
||
773 |
// Check bCSWStatus |
|
774 |
TInt bCSWStatus = cswBuf[CSW_LENGTH - 1]; |
|
775 |
test.Printf(_L("CSW status: %d\n"), bCSWStatus); |
|
776 |
LOG_AND_TEST(bCSWStatus, 1); |
|
777 |
||
778 |
//============================================ |
|
779 |
||
780 |
// Create a CBW for SCSI read (10) command to read the boot sector via MS FS |
|
781 |
TBuf8<SCSI_READ_LEN> readBuf; |
|
782 |
// 0: starting sector; 1: total blocks |
|
783 |
createReadCmd(readBuf, 0, 1); |
|
784 |
||
785 |
// 0x80: data-in to the host; 10: read (10) command length |
|
786 |
createCBW(cbwBuf, ++dCBWTag, BOOTSECTOR_SIZE, 0x80, 10, readBuf); |
|
787 |
||
788 |
||
789 |
// Send CBW to the LDD |
|
790 |
test.Next(_L("Send CBW with 'Read' Command")); |
|
791 |
usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); |
|
792 |
User::WaitForRequest(status); |
|
793 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
794 |
||
795 |
||
796 |
||
797 |
test.Next(_L("Reading bootsector data")); |
|
798 |
// Read the boot sector |
|
799 |
TBuf8<BOOTSECTOR_SIZE> msBootSector; |
|
800 |
usbcClient.HostRead(status, EEndpoint2, msBootSector, BOOTSECTOR_SIZE); |
|
801 |
User::WaitForRequest(status); |
|
802 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
803 |
||
804 |
// Read CSW |
|
805 |
test.Next(_L("Reading CSW")); |
|
806 |
usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); |
|
807 |
User::WaitForRequest(status); |
|
808 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
809 |
||
810 |
// Check dCBWTag |
|
811 |
recvedCBWTag = extractInt(&cswBuf[4]); |
|
812 |
LOG_AND_TEST(dCBWTag, recvedCBWTag); |
|
813 |
||
814 |
// Check bCSWStatus |
|
815 |
bCSWStatus = cswBuf[CSW_LENGTH - 1]; |
|
816 |
test.Printf(_L("CSW status: %d\n"), bCSWStatus); |
|
817 |
||
818 |
LOG_AND_TEST(bCSWStatus, 0); |
|
819 |
||
820 |
// Compare FAT FS boot sector with MS FS boot sector |
|
821 |
// When accessing the medium through USB, it is accessed raw. That means |
|
822 |
// we have to find the boot record (BPB), which may be in sector 0 if the |
|
823 |
// medium has no MBR or elsewhere if it is has a MBR. (Details of the |
|
824 |
// identification can be found in the FAT32 specification) |
|
825 |
TUint16 signature; |
|
826 |
||
827 |
signature = (TUint16) (msBootSector[KMBRSignatureOffset] | |
|
828 |
msBootSector[KMBRSignatureOffset + 1] << 8); |
|
829 |
||
830 |
LOG_AND_TEST(signature, KBootRecordSignature); |
|
831 |
||
832 |
if(((msBootSector[0] == 0xEB && msBootSector[2] == 0x90) || (msBootSector[0] == 0xE9)) && |
|
833 |
(msBootSector[16] >= 1) && ((msBootSector[21] == 0xF0) || (msBootSector[21] >= 0xF8))) |
|
834 |
{ |
|
835 |
test.Printf(_L("BPB identified in sector 0.\r\n")); |
|
836 |
} |
|
837 |
else |
|
838 |
{ |
|
839 |
test.Printf(_L("Assume sector 0 to be MBR - attempting to locate BPB\r\n")); |
|
840 |
// Read the offset to the first partition to find the boot record... |
|
841 |
// 32bit int stored as little endian |
|
842 |
TUint32 bootSectorLocation; |
|
843 |
bootSectorLocation = msBootSector[KMBRFirstPartitionSectorOffset] | |
|
844 |
msBootSector[KMBRFirstPartitionSectorOffset + 1] << 8 | |
|
845 |
msBootSector[KMBRFirstPartitionSectorOffset + 2] << 16 | |
|
846 |
msBootSector[KMBRFirstPartitionSectorOffset + 3] << 24; |
|
847 |
||
848 |
test.Printf(_L("Reading Boot Sector from offset %d\r\n"), bootSectorLocation); |
|
849 |
||
850 |
// Create a CBW for SCSI read (10) command to read the boot sector via MS FS |
|
851 |
TBuf8<SCSI_READ_LEN> readBuf; |
|
852 |
// 0: starting sector; 1: total blocks |
|
853 |
createReadCmd(readBuf, bootSectorLocation, 1); |
|
854 |
||
855 |
// 0x80: data-in to the host; 10: read (10) command length |
|
856 |
createCBW(cbwBuf, ++dCBWTag, BOOTSECTOR_SIZE, 0x80, 10, readBuf); |
|
857 |
||
858 |
// Send CBW to the LDD |
|
859 |
test.Next(_L("Send CBW with 'Read' Command")); |
|
860 |
usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); |
|
861 |
User::WaitForRequest(status); |
|
862 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
863 |
||
864 |
// Read the boot sector |
|
865 |
usbcClient.HostRead(status, EEndpoint2, msBootSector, BOOTSECTOR_SIZE); |
|
866 |
User::WaitForRequest(status); |
|
867 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
868 |
||
869 |
// Read CSW |
|
870 |
test.Next(_L("Reading CSW")); |
|
871 |
usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); |
|
872 |
User::WaitForRequest(status); |
|
873 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
874 |
||
875 |
// Check dCBWTag |
|
876 |
recvedCBWTag = extractInt(&cswBuf[4]); |
|
877 |
LOG_AND_TEST(dCBWTag, recvedCBWTag); |
|
878 |
||
879 |
// Check bCSWStatus |
|
880 |
bCSWStatus = cswBuf[CSW_LENGTH - 1]; |
|
881 |
test.Printf(_L("CSW status: %d\n"), bCSWStatus); |
|
882 |
||
883 |
LOG_AND_TEST(bCSWStatus, 0); |
|
884 |
} |
|
885 |
||
886 |
test (0 == fatBootSector.Compare(msBootSector)); |
|
887 |
||
888 |
// |
|
889 |
// Create a CBW to prevent medium removal |
|
890 |
// |
|
891 |
TBuf8<SCSI_MED_RMVL_LEN> tBuf; |
|
892 |
// Zero out the buf |
|
893 |
tBuf.FillZ(SCSI_MED_RMVL_LEN); |
|
894 |
tBuf[0] = 0x1E; |
|
895 |
tBuf[4] = 1; // prevent medium removal |
|
896 |
||
897 |
cbwBuf.FillZ(CBW_LENGTH); |
|
898 |
createCBW(cbwBuf, ++dCBWTag, 0, 0, SCSI_MED_RMVL_LEN, tBuf); |
|
899 |
||
900 |
// Send prevent medium removal command |
|
901 |
test.Next(_L("Sending CBW with 'Prevent media removal' cmd")); |
|
902 |
usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); |
|
903 |
User::WaitForRequest(status); |
|
904 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
905 |
||
906 |
// Read CSW |
|
907 |
test.Next(_L("Reading CSW")); |
|
908 |
usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); |
|
909 |
User::WaitForRequest(status); |
|
910 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
911 |
||
912 |
// Check dCSWTag |
|
913 |
recvedCBWTag = extractInt(&cswBuf[4]); |
|
914 |
LOG_AND_TEST(dCBWTag, recvedCBWTag); |
|
915 |
||
916 |
// Check bCSWStatus |
|
917 |
bCSWStatus = cswBuf[CSW_LENGTH - 1]; |
|
918 |
test.Printf(_L("CSW status: %d\n"), bCSWStatus); |
|
919 |
||
920 |
if(bCSWStatus == 0) |
|
921 |
{ |
|
922 |
||
923 |
// Try to unmount MS FS. This should fail as medium removal is disallowed |
|
924 |
test.Next(_L("Dismounting MSFS")); |
|
925 |
test(KErrNone != fs.DismountFileSystem(KMsFsyName, removalDrvNo)); |
|
926 |
||
927 |
// |
|
928 |
// Create a CBW to allow medium removal |
|
929 |
// |
|
930 |
// Zero out the buf |
|
931 |
tBuf.FillZ(SCSI_MED_RMVL_LEN); |
|
932 |
tBuf[0] = 0x1E; |
|
933 |
tBuf[4] = 0; // allow medium removal |
|
934 |
||
935 |
createCBW(cbwBuf, ++dCBWTag, 0, 0, SCSI_MED_RMVL_LEN, tBuf); |
|
936 |
||
937 |
// Send allow medium removal command |
|
938 |
test.Next(_L("Sending CBW with 'Allow media removal' cmd")); |
|
939 |
usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); |
|
940 |
User::WaitForRequest(status); |
|
941 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
942 |
||
943 |
// Read CSW |
|
944 |
test.Next(_L("Reading CSW")); |
|
945 |
usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); |
|
946 |
User::WaitForRequest(status); |
|
947 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
948 |
||
949 |
// Check dCSWTag |
|
950 |
recvedCBWTag = extractInt(&cswBuf[4]); |
|
951 |
LOG_AND_TEST(dCBWTag, recvedCBWTag); |
|
952 |
||
953 |
// Check bCSWStatus |
|
954 |
bCSWStatus = cswBuf[CSW_LENGTH - 1]; |
|
955 |
test.Printf(_L("CSW status: %d\n"), bCSWStatus); |
|
956 |
LOG_AND_TEST(bCSWStatus, 0); |
|
957 |
||
958 |
} |
|
959 |
else |
|
960 |
test.Printf(_L("Prevent Media Removal command not supported, skipping appropriate tests")); |
|
961 |
||
962 |
||
963 |
// Try to unmount MS FS again. This time it should succeed |
|
964 |
LOG_AND_TEST(KErrNone, fs.DismountFileSystem(KMsFsyName, removalDrvNo)); |
|
965 |
||
966 |
// Read the boot sector while MS FS is unmounted, this should fail |
|
967 |
test(KErrNone != fatDiskF.Open(fs, removalDrvNo)); |
|
968 |
fatDiskF.Close(); |
|
969 |
||
970 |
// Mount FAT FS on to the removal drive |
|
971 |
LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); |
|
972 |
||
973 |
// Additional step for DEF079149: File server crash when re-adding |
|
974 |
// MSFS.FSY. Before the fix was applied this call to RFs::AddFileSystem |
|
975 |
// would cause a crash. |
|
976 |
LOG_AND_TEST(KErrAlreadyExists,fs.AddFileSystem(KMsFs)); |
|
977 |
||
978 |
// Read the boot sector after FAT MS is mounted on to the removal drive |
|
979 |
LOG_AND_TEST(KErrNone, fatDiskF.Open(fs, removalDrvNo)); |
|
980 |
LOG_AND_TEST(KErrNone, fatDiskF.Read(0, fatBootSector)); |
|
981 |
fatDiskF.Close(); |
|
982 |
||
983 |
createCBW(cbwBuf, ++dCBWTag, 0, 0, SCSI_UNIT_READY_LEN, unitReadyBuf); |
|
984 |
||
985 |
// Send test unit ready command |
|
986 |
test.Next(_L("Sending CBW with 'Unit Ready' cmd")); |
|
987 |
usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); |
|
988 |
User::WaitForRequest(status); |
|
989 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
990 |
||
991 |
// Read CSW |
|
992 |
usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); |
|
993 |
User::WaitForRequest(status); |
|
994 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
995 |
||
996 |
// Check dCSWTag |
|
997 |
recvedCBWTag = extractInt(&cswBuf[4]); |
|
998 |
LOG_AND_TEST(dCBWTag, recvedCBWTag); |
|
999 |
||
1000 |
// Check bCSWStatus |
|
1001 |
bCSWStatus = cswBuf[CSW_LENGTH - 1]; |
|
1002 |
test.Printf(_L("CSW status: %d\n"), bCSWStatus); |
|
1003 |
LOG_AND_TEST(bCSWStatus, 1); |
|
1004 |
||
1005 |
// |
|
1006 |
// Read MS FS using SCSI read command, this should fail as |
|
1007 |
// FAT FS is mounted instead |
|
1008 |
// |
|
1009 |
||
1010 |
// 0x80: data-in to the host; 10: read (10) command length |
|
1011 |
||
1012 |
createCBW(cbwBuf, ++dCBWTag, BOOTSECTOR_SIZE, 0x80, 10, readBuf); |
|
1013 |
||
1014 |
// Send CBW to the LDD |
|
1015 |
test.Next(_L("SEnding CBW with 'Read'")); |
|
1016 |
usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); |
|
1017 |
User::WaitForRequest(status); |
|
1018 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
1019 |
||
1020 |
// Read the sector |
|
1021 |
usbcClient.HostRead(status, EEndpoint2, msBootSector, BOOTSECTOR_SIZE); |
|
1022 |
User::WaitForRequest(status); |
|
1023 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
1024 |
||
1025 |
||
1026 |
// Read CSW |
|
1027 |
usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); |
|
1028 |
User::WaitForRequest(status); |
|
1029 |
LOG_AND_TEST(KErrNone, status.Int()); |
|
1030 |
||
1031 |
// Check dCSWTag |
|
1032 |
recvedCBWTag = extractInt(&cswBuf[4]); |
|
1033 |
LOG_AND_TEST(dCBWTag , recvedCBWTag); |
|
1034 |
||
1035 |
// Check bCSWStatus |
|
1036 |
bCSWStatus = cswBuf[CSW_LENGTH - 1]; |
|
1037 |
test.Printf(_L("CSW status: %d\n"), bCSWStatus); |
|
1038 |
test(bCSWStatus != 0); |
|
1039 |
||
1040 |
||
1041 |
// Read FAT FS using RFs API |
|
1042 |
LOG_AND_TEST(KErrNone, fatDiskF.Open(fs, removalDrvNo)); |
|
1043 |
LOG_AND_TEST(KErrNone, fatDiskF.Read(0, fatBootSector)); |
|
1044 |
fatDiskF.Close(); |
|
1045 |
||
1046 |
// Stop usb mass storage device |
|
1047 |
LOG_AND_TEST(KErrNone, usbMs.Stop()); |
|
1048 |
usbMs.Close(); |
|
1049 |
User::After(1000000); |
|
1050 |
||
1051 |
ret = fs.RemoveFileSystem(KMsFsyName); |
|
1052 |
fs.Close(); |
|
1053 |
||
1054 |
usbcClient.Close(); |
|
1055 |
ret = User::FreeLogicalDevice(_L("USBC")); |
|
1056 |
LOG_AND_TEST(ret, KErrNone); |
|
1057 |
||
1058 |
test.Printf(_L("Exiting test\r\n")); |
|
1059 |
__UHEAP_MARKEND; |
|
1060 |
} |
|
1061 |
||
1062 |
||
1063 |
||
1064 |
GLDEF_C void CallTestsL() |
|
1065 |
// |
|
1066 |
// Do all tests |
|
1067 |
// |
|
1068 |
{ |
|
1069 |
// Parse the CommandLine arguments: removal drive and non-removal drive |
|
1070 |
ParseCommandArguments(); |
|
1071 |
||
1072 |
// Run test |
|
1073 |
test.Start( _L("Test mountstart") ); |
|
1074 |
doComponentTest(); |
|
1075 |
test.End(); |
|
1076 |
} |