BlockStorageDeviceDriverKit

RSS for tag

Develop drivers for block storage devices using BlockStorageDeviceDriverKit.

Posts under BlockStorageDeviceDriverKit tag

9 Posts

Post

Replies

Boosts

Views

Activity

INQUIRY command is ILLEGAL REQUEST
I am developing a DriverKit driver with the goal of sending vendor-specific commands to a USB storage device. I have successfully created the DriverKit driver, and when I connect the USB storage device, it appears correctly in IORegistryExplorer. My driver class inherits from IOUserSCSIPeripheralDeviceType00 in the SCSIPeripheralsDriverKit framework. I also created a UserClient class that inherits from IOUserClient, and from its ExternalMethod I tried sending an INQUIRY command as a basic test to confirm that command transmission works. However, the device returns an ILLEGAL REQUEST (Sense Key 0x5 / ASC 0x20). Could someone advise what I might be doing wrong? Below are the logs output from the driver: 2025-11-14 21:00:43.573730+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] Driver - NewUserClient() - Finished. 2025-11-14 21:00:43.573733+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - Start() 2025-11-14 21:00:43.573807+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - Start() - Finished. 2025-11-14 21:00:43.574249+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - ExternalMethod() called 2025-11-14 21:00:43.574258+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - ----- SCSICmdINQUIRY ----- 2025-11-14 21:00:43.574268+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - command.fRequestedByteCountOfTransfer = 512 2025-11-14 21:00:43.575980+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB fCompletionStatus = 0x0 2025-11-14 21:00:43.575988+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB fServiceResponse = 0x2 2025-11-14 21:00:43.575990+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB fSenseDataValid = 0x1 2025-11-14 21:00:43.575992+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB VALID_RESPONSE_CODE = 0x70 2025-11-14 21:00:43.575994+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB SENSE_KEY = 0x5 2025-11-14 21:00:43.575996+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB ADDITIONAL_SENSE_CODE = 0x20 2025-11-14 21:00:43.575998+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB ADDITIONAL_SENSE_CODE_QUALIFIER = 0x0 Here is the UserClient class: class SampleDriverKitUserClient: public IOUserClient { public: virtual bool init(void) override; virtual kern_return_t Start(IOService* provider) override; virtual kern_return_t Stop(IOService* provider) override; virtual void free(void) override; virtual kern_return_t ExternalMethod( uint64_t selector, IOUserClientMethodArguments* arguments, const IOUserClientMethodDispatch* dispatch, OSObject* target, void* reference) override; void SCSICmdINQUIRY(SampleDriverKitDriver *driver) LOCALONLY; }; Here is the part that sends the INQUIRY command: void SampleDriverKitUserClient::SCSICmdINQUIRY(SampleDriverKitDriver *driver) { kern_return_t kr = KERN_SUCCESS; SCSIType00OutParameters command = {}; UInt8 dataBuffer[512] = {0}; SCSI_Sense_Data senseData = {0}; Log("----- SCSICmdINQUIRY -----"); SetCommandCDB(&command.fCommandDescriptorBlock, 0x12, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); command.fLogicalUnitNumber = 0; command.fTimeoutDuration = 10000; // milliseconds command.fRequestedByteCountOfTransfer = sizeof(dataBuffer); Log("command.fRequestedByteCountOfTransfer = %lld", command.fRequestedByteCountOfTransfer); command.fBufferDirection = kIOMemoryDirectionIn; command.fDataTransferDirection = kSCSIDataTransfer_FromTargetToInitiator; command.fDataBufferAddr = reinterpret_cast<uint64_t>(dataBuffer); command.fSenseBufferAddr = reinterpret_cast<uint64_t>(&senseData); command.fSenseLengthRequested = sizeof(senseData); if( driver ) { SCSIType00InParameters response = {}; kr = driver->UserSendCDB(command, &response); if( kr != KERN_SUCCESS ) { Log("SCSICmdINQUIRY() UserSendCDB failed (0x%x)", kr); return; } Log("SCSICmdINQUIRY() UserSendCDB fCompletionStatus = 0x%x", response.fCompletionStatus); Log("SCSICmdINQUIRY() UserSendCDB fServiceResponse = 0x%x", response.fServiceResponse); Log("SCSICmdINQUIRY() UserSendCDB fSenseDataValid = 0x%x", response.fSenseDataValid); Log("SCSICmdINQUIRY() UserSendCDB VALID_RESPONSE_CODE = 0x%x", senseData.VALID_RESPONSE_CODE); Log("SCSICmdINQUIRY() UserSendCDB SENSE_KEY = 0x%x", senseData.SENSE_KEY); Log("SCSICmdINQUIRY() UserSendCDB ADDITIONAL_SENSE_CODE = 0x%x", senseData.ADDITIONAL_SENSE_CODE); Log("SCSICmdINQUIRY() UserSendCDB ADDITIONAL_SENSE_CODE_QUALIFIER = 0x%x", senseData.ADDITIONAL_SENSE_CODE_QUALIFIER); if( response.fServiceResponse == kSCSIServiceResponse_TASK_COMPLETE ) { Log("SCSICmdINQUIRY() UserSendCDB complete success!!"); } for( int i=0; i < 5; i++ ) { Log("data [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x", i*8+0, dataBuffer[i*8+0], i*8+1, dataBuffer[i*8+1], i*8+2, dataBuffer[i*8+2], i*8+3, dataBuffer[i*8+3], i*8+4, dataBuffer[i*8+4], i*8+5, dataBuffer[i*8+5], i*8+6, dataBuffer[i*8+6], i*8+7, dataBuffer[i*8+7] ); } char vendorID[9] = {0}; memcpy(vendorID, &dataBuffer[8], 8); Log("vendorID = %s",vendorID); char productID[17] = {0}; memcpy(productID, &dataBuffer[16], 16); Log("productID = %s",productID); } } My environment is: MacBook Pro (M2), macOS 15.6 If anyone has insight into what causes the ILLEGAL REQUEST, or what I am missing when using IOUserSCSIPeripheralDeviceType00 and UserSendCDB, I would greatly appreciate your help. Thank you.
1
0
500
Nov ’25
How to implement NVMESMARTLib for USB-NVMe bridge chip?
Many USB storage devices are NVMe devices accessed through a USB-NVMe bridge chip, such as those by JMicron and Asmedia. These chipsets do not forward SMART data requests to the devices, but do have the capability to forward raw NVMe commands to the devices using vendor specific requests. How can we provide access to SMART data for NVMe devices accessed through a bridge chip like this? Many people used the OSX SAT SMART kext driver to provide access to SMART data for devices using USB-SATA chips, but it is a kext and doesn't support NVMe. See https://binaryfruit.com/drivedx/usb-drive-support#install-instructions Would we need to implement a kext like that to make this work? Is there a DriverKit way to do this?
4
0
1.3k
Jul ’24
How to let the system take over a device after the DriverKit process exits?
I have created a USB filter using Mac DriverKit, but the filter is unable to retrieve configuration information during startup. After the USB filter has started and registered the service, my app can send the configuration information to the filter. Therefore, I would like to know if there is a way to exit the USB filter and allow the system to take control of the USB device once the filter has exited. I have tried calling Terminate(0), but it did not work as even after the USB filter exited, the Finder still couldn't display the USB device.
0
0
687
Nov ’23
How does the driverkit serve as a bridge between hardware and the system?
I want to use DriverKit to develop a USBDriver, which serves as a bridge between USB devices and the system. All messages between USB devices and the system will be forwarded through the USBDriver. Can anyone give me some tips or suggestions? What API should I use? I couldn't find anything like this in the documentation or sample code. class MyUSBDriver: public IOUserClient { public: virtual bool init() override; virtual kern_return_t Start(IOService * provider) override; virtual kern_return_t Stop(IOService * provider) override; virtual void free() override; virtual kern_return_t GetRegistryEntryID(uint64_t * registryEntryID) override; virtual kern_return_t NewUserClient(uint32_t type, IOUserClient** userClient) override; virtual kern_return_t ExternalMethod(uint64_t selector, IOUserClientMethodArguments* arguments, const IOUserClientMethodDispatch* dispatch, OSObject* target, void* reference) override; }; I am now able to retrieve the device descriptor in the Start method IOUSBHostDevice *device = OSDynamicCast(IOUSBHostDevice, provider); if (device) { const IOUSBDeviceDescriptor *deviceDescriptor = device->CopyDeviceDescriptor(); if (deviceDescriptor) { uint16_t idVendor = deviceDescriptor->idVendor; uint16_t idProduct = deviceDescriptor->idProduct; uint8_t iSerialNumber = deviceDescriptor->iSerialNumber; IOUSBHostFreeDescriptor(deviceDescriptor); } }
0
0
733
Nov ’23
DiskUtility inode warnings wont clear up with FirstAde
Hello everyone, I am running 14.0 (23A344) and have sporadic issues like operation not being permitted when trying to remove some folders in ~/Library after some application was uninstalled using AppCleaner.app, which I have used for years. It works 99% of the time, but sometimes I get errors that some files/folders in ~/Library can not be removed. If I try to "sudo rm -rf" that folder from Terminal, I get operation not permitted. So this did bring me to DiskUtility. I am running MBP 14 M1 Pro. As always when I get a new machine, the first thing I do is reformat SSD to Case Sensitive Encrypted from default Case Insensitive since that gives me issues with my source code compilation when developed between Mac and Linux. Here is my Disk Util. I do not get any warnings on any other partitions/sections under and including "Macintosh HD volume" at the top of the hierarchy. When I run FirstAid on the Data partition, I get the following warnings. Now I can run this repeatedly, and the same errors are produced. I can do a reboot in between running Disk Utilities, and the same warnings. I did boot to Safe Mode and run Disk Utility, and the same warnings. I contacted Apple support and have a case: 102125788648, but I was also instructed to create a case here. Here is my side story, why I can not use Time Machine. As a last resort, I was asked to reformat and reinstall. That is not an option for me at this point since restoring everything is a 1-2 day job. Now, I know there is a Time Machine, but on my two attempts in the past, backups created on brand new external Samsung 970 Pro SSD failed to restore. These two backups/restores were a few months apart. So on the second support call, it was suggested by support to back/restore using TimeMachine. After stating that I had a horror story on my first attempt a few months back, I was assured that the issue had been fixed and I should not have an issue. Oh well, same issue. After spending considerable time with support (a few folks) they noticed that the Time Machine folder structure was wrong and some intermediate folder was missing causing the issue. In both cases, I never heard anything back if it was addressed/fixed, except the support during the second case, assured me that it was fixed. That is why I did try to use Time Machine with him to back up while he was screensharing to make sure I did not do anything unusual. Still, restoration failed. So even Time Machine should make restoration painless, for it was pain, since on the first occasion I lost all the files. On second I could brow Time Machine folders in Terminal and pick files/folders from there. Took a long time. And to throw another strange case, I could only access them from Terminal under my wife's machine which is running an older Mac, but the new restored Mac I "was not able"! which is very weird. Both machines were at the time Intel machines. So I never attempted to use TimeMachine again on M1 Pro. So I hope everyone sees why I do not want to reformat and restore. Now, I have a feeling that most of my problems might be related to Case Sensitive reformated SSD. I can not go back to Case Insensitive (default), as I explained above. I am here to provide any information to help get this fixed. Any suggestions or anything to try? Robert
0
0
956
Oct ’23
How to access dmaaddress (Physical Address) in DriverKit?
I am trying to use IOUserBlockStorageDevice in DriverKit to simulate a fake device (Implementing a Ram Disk). Currently I'm confused on how to use the dmaaddress in the following interface virtual kern_return_t DoAsyncReadWrite (bool isRead, uint32_t requestID, uint64_t dmaAddr, uint64_t size, uint64_t lba, uint64_t numOfBlocks, IOUserStorageOptions options) = 0; According to https://github.com/briancabbott/macOS-system-projects/blob/19310aa5c7b7507408261a22a2e8f46f9d478a88/Resources/Code/apple-oss-distributions/IOStorageFamily/IOUserBlockStorageDevice_kext.cpp Before calling "DoAsyncReadWrite", kernel allocate a segment of physical memory by using "IODMAcommand::genIOVMSegments". This segment's physical address is pass to DoAsyncReadWrite as parameter "dmaAddr". To implement a correct ram disk, we need to "transform" this physical address to virtual so that we can "Read" or "Write" on this physical address. I tried to use "IOMemoryDescriptor" to access this dmaAddr. In IOKit, I belive I can use interface such as "withPhysicalAddress" to access the memory. However, such interface is not exist while using driverkit, all interface that I can use in DriverKit IOMemoryDescriptor is : -kern_return_t GetLength(uint64_t * returnLength) LOCALONLY; // apparently not this one -virtual kern_return_t CreateMapping( uint64_t options, uint64_t address, uint64_t offset, uint64_t length, uint64_t alignment, IOMemoryMap ** map); // Maybe this one with kIOMemoryFixedAddress option? // But I get Segment Fault while calling this with CreateMapping( kIOMemoryFixedAddress , dmaaddr, 0, size, 0, &map); // Or getting error return while calling CreateMapping with same paramters after IOBufferMemoryDescriptor::Create // Also, output iomemorymap is not used here, which is quiet strange. static kern_return_t CreateSubMemoryDescriptor(uint64_t memoryDescriptorCreateOptions, uint64_t offset, uint64_t length, IOMemoryDescriptor * ofDescriptor, IOMemoryDescriptor ** memory) attribute((availability(driverkit,introduced=20.0))); // Seems not this, it create “sub“ memory descriptor static kern_return_t CreateWithMemoryDescriptors(uint64_t memoryDescriptorCreateOptions, uint32_t withDescriptorsCount, IOMemoryDescriptor * const withDescriptors[32], IOMemoryDescriptor ** memory) attribute((availability(driverkit,introduced=20.0))); // Seems not this, it don’t take any dmaaddr as parameter. and a private function kern_return_t Map( uint64_t options, uint64_t address, uint64_t length, uint64_t alignment, uint64_t * returnAddress, uint64_t * returnLength) LOCALONLY; // Maybe this one? But the header file don’t show any description on this function and we are not sure what parameters should we pass. // Currently I've test Map( kIOMemoryFixedAddress , dmaaddr, size, 0, &returnAddress, &returnLength) but get error return. It seems that I've made some mistake on using IOMemoryDescriptor? How to correct access a dmaaddress? I've also tried class "IODMACommand", but also get unexpected behavior. Another question is how to read / write buffer after I create correct mapping. While implementing kext, IOMemoryDescriptor can use "readBytes" or "writeBytes" to read or write memory that IOMemoryDescriptor maps to. However, DriverKit don’t have interface of "readBytes" or "writeBytes". Maybe I can directly access buffer by casting the IOMemoryDescriptor::Map "returnAddress" to void? (I haven't tried it yet cause "Map" always failed now QQ) Thanks for everyone's help.
2
1
2.4k
Feb ’23
How to correctly create IOUserBlockStorageDevice through iouserclient?
I'm currently use IOUserBlockStorageDevice to simulate a ram disk. To simulate a pluggable ramdisk that can commute, I would like to use a hierarcy architecture. However, something strange happened while I'm using hierarcy architecture. The hierarcy architecture might shows as following in ioreg ... +-o IOUserResources <class IOUserResources, id 0x10000011b, registered, matched, active, busy 0 (571 ms), retain 9> | +-o IOUserDockChannelSerial <class IOUserService, id 0x10000040c, registered, matched, active, busy 0 (0 ms), retain 8> | +-o MyService <class IOUserService, id 0x10000040d, registered, matched, active, busy 0 (2 ms), retain 9> | +-o MyUserClient <class IOUserUserClient, id 0x100000760, registered, matched, active, busy 0 (2 ms), retain 9> | +-o MyDevice <class IOUserBlockStorageDevice, id 0x100000762, registered, matched, active, busy 0 (2 ms), retain 8> | +-o IOBlockStorageDriver <class IOBlockStorageDriver, id 0x100000763, registered, matched, active, busy 0 (1 ms), retain 8> | +-o Testing Media <class IOMedia, id 0x100000764, registered, matched, active, busy 0 (1 ms), retain 9> | +-o IOMediaBSDClient <class IOMediaBSDClient, id 0x100000765, registered, matched, active, busy 0 (0 ms), retain 6> +-o IOUserServer(com.apple.IOUserDockChannelSerial-0x10000040c) <class IOUserServer, id 0x100000472, registered, matched, active, busy 0 (0 ms), retain 11> +-o IOUserServer(com.example.apple-samplecode.dext-to-user-client.driver-0x10000040d) <class IOUserServer, id 0x100000474, registered, matched, active, busy 0 (0 ms), retain 13> MyService is the loaded dext, which create an UserClient while a client connect. MyUserClient has two interface: adddevice / remove which will add or remove a MyDevice instance. MyDevice is the IOUserBlockStorageDevice create by MyuserClient. I'm using the following plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>$(DEVELOPMENT_LANGUAGE)</string> <key>CFBundleExecutable</key> <string>$(EXECUTABLE_NAME)</string> <key>CFBundleIdentifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>$(PRODUCT_NAME)</string> <key>CFBundlePackageType</key> <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleVersion</key> <string>1</string> <key>IOKitPersonalities</key> <dict> <key>testDevice</key> <dict> <key>CFBundleIdentifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleIdentifierKernel</key> <string>com.apple.kpi.iokit</string> <key>IOClass</key> <string>IOUserService</string> <key>IOMatchCategory</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>IOProviderClass</key> <string>IOUserResources</string> <key>IOResourceMatch</key> <string>IOKit</string> <key>IOUserClass</key> <string>MyService</string> <key>IOUserServerName</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>UserClientProperties</key> <dict> <key>MyDeviceProperties</key> <dict> <key>CFBundleIdentifierKernel</key> <string>com.apple.iokit.IOStorageFamily</string> <key>IOClass</key> <string>IOUserBlockStorageDevice</string> <key>IOUserClass</key> <string>MyDevice</string> </dict> <key>IOClass</key> <string>IOUserUserClient</string> <key>IOUserClass</key> <string>MyUserClient</string> </dict> </dict> </dict> <key>OSBundleUsageDescription</key> <string></string> </dict> </plist> and MyDevice is create by "auto kr = Create(this, "MyDeviceProperties", &client);" in MyUserClient. To make sure the flow of MyDevice, I add an simple log (inside xxx function) while entering each function implement. Following is the system log after adddevice: === ExternalMethod AddDevice === 2022-10-21 12:08:20.424783+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient ccc Inside ExternalMethod!!!!! 2022-10-21 12:08:20.424803+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient ExternalMethodType_AddDevice 2022-10-21 12:08:20.424812+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient NewDevice 2022-10-21 12:08:20.424847+0800 0xcd3cd Default 0x0 0 0 kernel: (IOStorageFamily) INFO virtual bool IOUserBlockStorageDevice::init(OSDictionary *): Allocate resources 2022-10-21 12:08:20.425059+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice init..... 2022-10-21 12:08:20.425145+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice init done 2022-10-21 12:08:20.425152+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Start 2022-10-21 12:08:20.425158+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) IOUserBlockStorageDevice::Start() 2022-10-21 12:08:20.425201+0800 0xcd3cd Default 0x0 0 0 kernel: (IOStorageFamily) INFO kern_return_t IOUserBlockStorageDevice::RegisterDext_Impl(): Registering dext 2022-10-21 12:08:20.425212+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Reg service 2022-10-21 12:08:20.425270+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Start() - Finished. 2022-10-21 12:08:20.425281+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient NewDevice done 2022-10-21 12:08:20.425598+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside ReportRemovability 2022-10-21 12:08:20.425852+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside ReportWriteProtection 2022-10-21 12:08:20.425916+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside GetVendorString 2022-10-21 12:08:20.426022+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside GetProductString <log end, device stuch here> The IOUserBlockStorageDevice stuck after calling GetProductString, not called GetDeviceParam, and the device size remains be zero in this case. I'm not sure why MyDevice stuck. Could anyone help for this case? I'll post some detailed test in reply.
1
0
1.7k
Nov ’22
IOS16 Browser: LocalStorage is cleared after writing data of more than ~2.5MB
IOS16 Safari: LocalStorage is cleared after writing data of more than ~2.5MB. After upgrading to IOS 16 we faced the problem of clearing data in localStorage.When we try to write data that size is more than ~2.5MB or all amounts of data more than ~2.5MB the LocalStorage is being cleared without any errors and warnings in Safari. I could not reproduce the problem in other browsers or platforms. Step to reproduce: Go to IOS 16 Safari Open any website try to write data more than ~2.5MB (the attached defineMaxSizeLs.js test script helps you to display the problem) check your localStorage Actual result: your localStorage is empty Expected result: your localStorage should be filled your data or it should be thrown an exception if the quota is exceeded Please consider the problem ASAP. Thank you in advance!
2
1
4.5k
Sep ’22
INQUIRY command is ILLEGAL REQUEST
I am developing a DriverKit driver with the goal of sending vendor-specific commands to a USB storage device. I have successfully created the DriverKit driver, and when I connect the USB storage device, it appears correctly in IORegistryExplorer. My driver class inherits from IOUserSCSIPeripheralDeviceType00 in the SCSIPeripheralsDriverKit framework. I also created a UserClient class that inherits from IOUserClient, and from its ExternalMethod I tried sending an INQUIRY command as a basic test to confirm that command transmission works. However, the device returns an ILLEGAL REQUEST (Sense Key 0x5 / ASC 0x20). Could someone advise what I might be doing wrong? Below are the logs output from the driver: 2025-11-14 21:00:43.573730+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] Driver - NewUserClient() - Finished. 2025-11-14 21:00:43.573733+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - Start() 2025-11-14 21:00:43.573807+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - Start() - Finished. 2025-11-14 21:00:43.574249+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - ExternalMethod() called 2025-11-14 21:00:43.574258+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - ----- SCSICmdINQUIRY ----- 2025-11-14 21:00:43.574268+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - command.fRequestedByteCountOfTransfer = 512 2025-11-14 21:00:43.575980+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB fCompletionStatus = 0x0 2025-11-14 21:00:43.575988+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB fServiceResponse = 0x2 2025-11-14 21:00:43.575990+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB fSenseDataValid = 0x1 2025-11-14 21:00:43.575992+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB VALID_RESPONSE_CODE = 0x70 2025-11-14 21:00:43.575994+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB SENSE_KEY = 0x5 2025-11-14 21:00:43.575996+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB ADDITIONAL_SENSE_CODE = 0x20 2025-11-14 21:00:43.575998+0900 0x26e9 Default 0x0 0 0 kernel: (SampleDriverKitApp.SampleDriverKitDriver.dext) [DEBUG] UserClient - SCSICmdINQUIRY() UserSendCDB ADDITIONAL_SENSE_CODE_QUALIFIER = 0x0 Here is the UserClient class: class SampleDriverKitUserClient: public IOUserClient { public: virtual bool init(void) override; virtual kern_return_t Start(IOService* provider) override; virtual kern_return_t Stop(IOService* provider) override; virtual void free(void) override; virtual kern_return_t ExternalMethod( uint64_t selector, IOUserClientMethodArguments* arguments, const IOUserClientMethodDispatch* dispatch, OSObject* target, void* reference) override; void SCSICmdINQUIRY(SampleDriverKitDriver *driver) LOCALONLY; }; Here is the part that sends the INQUIRY command: void SampleDriverKitUserClient::SCSICmdINQUIRY(SampleDriverKitDriver *driver) { kern_return_t kr = KERN_SUCCESS; SCSIType00OutParameters command = {}; UInt8 dataBuffer[512] = {0}; SCSI_Sense_Data senseData = {0}; Log("----- SCSICmdINQUIRY -----"); SetCommandCDB(&command.fCommandDescriptorBlock, 0x12, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); command.fLogicalUnitNumber = 0; command.fTimeoutDuration = 10000; // milliseconds command.fRequestedByteCountOfTransfer = sizeof(dataBuffer); Log("command.fRequestedByteCountOfTransfer = %lld", command.fRequestedByteCountOfTransfer); command.fBufferDirection = kIOMemoryDirectionIn; command.fDataTransferDirection = kSCSIDataTransfer_FromTargetToInitiator; command.fDataBufferAddr = reinterpret_cast<uint64_t>(dataBuffer); command.fSenseBufferAddr = reinterpret_cast<uint64_t>(&senseData); command.fSenseLengthRequested = sizeof(senseData); if( driver ) { SCSIType00InParameters response = {}; kr = driver->UserSendCDB(command, &response); if( kr != KERN_SUCCESS ) { Log("SCSICmdINQUIRY() UserSendCDB failed (0x%x)", kr); return; } Log("SCSICmdINQUIRY() UserSendCDB fCompletionStatus = 0x%x", response.fCompletionStatus); Log("SCSICmdINQUIRY() UserSendCDB fServiceResponse = 0x%x", response.fServiceResponse); Log("SCSICmdINQUIRY() UserSendCDB fSenseDataValid = 0x%x", response.fSenseDataValid); Log("SCSICmdINQUIRY() UserSendCDB VALID_RESPONSE_CODE = 0x%x", senseData.VALID_RESPONSE_CODE); Log("SCSICmdINQUIRY() UserSendCDB SENSE_KEY = 0x%x", senseData.SENSE_KEY); Log("SCSICmdINQUIRY() UserSendCDB ADDITIONAL_SENSE_CODE = 0x%x", senseData.ADDITIONAL_SENSE_CODE); Log("SCSICmdINQUIRY() UserSendCDB ADDITIONAL_SENSE_CODE_QUALIFIER = 0x%x", senseData.ADDITIONAL_SENSE_CODE_QUALIFIER); if( response.fServiceResponse == kSCSIServiceResponse_TASK_COMPLETE ) { Log("SCSICmdINQUIRY() UserSendCDB complete success!!"); } for( int i=0; i < 5; i++ ) { Log("data [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x [%04d]=0x%x", i*8+0, dataBuffer[i*8+0], i*8+1, dataBuffer[i*8+1], i*8+2, dataBuffer[i*8+2], i*8+3, dataBuffer[i*8+3], i*8+4, dataBuffer[i*8+4], i*8+5, dataBuffer[i*8+5], i*8+6, dataBuffer[i*8+6], i*8+7, dataBuffer[i*8+7] ); } char vendorID[9] = {0}; memcpy(vendorID, &dataBuffer[8], 8); Log("vendorID = %s",vendorID); char productID[17] = {0}; memcpy(productID, &dataBuffer[16], 16); Log("productID = %s",productID); } } My environment is: MacBook Pro (M2), macOS 15.6 If anyone has insight into what causes the ILLEGAL REQUEST, or what I am missing when using IOUserSCSIPeripheralDeviceType00 and UserSendCDB, I would greatly appreciate your help. Thank you.
Replies
1
Boosts
0
Views
500
Activity
Nov ’25
How to implement NVMESMARTLib for USB-NVMe bridge chip?
Many USB storage devices are NVMe devices accessed through a USB-NVMe bridge chip, such as those by JMicron and Asmedia. These chipsets do not forward SMART data requests to the devices, but do have the capability to forward raw NVMe commands to the devices using vendor specific requests. How can we provide access to SMART data for NVMe devices accessed through a bridge chip like this? Many people used the OSX SAT SMART kext driver to provide access to SMART data for devices using USB-SATA chips, but it is a kext and doesn't support NVMe. See https://binaryfruit.com/drivedx/usb-drive-support#install-instructions Would we need to implement a kext like that to make this work? Is there a DriverKit way to do this?
Replies
4
Boosts
0
Views
1.3k
Activity
Jul ’24
How to let the system take over a device after the DriverKit process exits?
I have created a USB filter using Mac DriverKit, but the filter is unable to retrieve configuration information during startup. After the USB filter has started and registered the service, my app can send the configuration information to the filter. Therefore, I would like to know if there is a way to exit the USB filter and allow the system to take control of the USB device once the filter has exited. I have tried calling Terminate(0), but it did not work as even after the USB filter exited, the Finder still couldn't display the USB device.
Replies
0
Boosts
0
Views
687
Activity
Nov ’23
How does the driverkit serve as a bridge between hardware and the system?
I want to use DriverKit to develop a USBDriver, which serves as a bridge between USB devices and the system. All messages between USB devices and the system will be forwarded through the USBDriver. Can anyone give me some tips or suggestions? What API should I use? I couldn't find anything like this in the documentation or sample code. class MyUSBDriver: public IOUserClient { public: virtual bool init() override; virtual kern_return_t Start(IOService * provider) override; virtual kern_return_t Stop(IOService * provider) override; virtual void free() override; virtual kern_return_t GetRegistryEntryID(uint64_t * registryEntryID) override; virtual kern_return_t NewUserClient(uint32_t type, IOUserClient** userClient) override; virtual kern_return_t ExternalMethod(uint64_t selector, IOUserClientMethodArguments* arguments, const IOUserClientMethodDispatch* dispatch, OSObject* target, void* reference) override; }; I am now able to retrieve the device descriptor in the Start method IOUSBHostDevice *device = OSDynamicCast(IOUSBHostDevice, provider); if (device) { const IOUSBDeviceDescriptor *deviceDescriptor = device->CopyDeviceDescriptor(); if (deviceDescriptor) { uint16_t idVendor = deviceDescriptor->idVendor; uint16_t idProduct = deviceDescriptor->idProduct; uint8_t iSerialNumber = deviceDescriptor->iSerialNumber; IOUSBHostFreeDescriptor(deviceDescriptor); } }
Replies
0
Boosts
0
Views
733
Activity
Nov ’23
DiskUtility inode warnings wont clear up with FirstAde
Hello everyone, I am running 14.0 (23A344) and have sporadic issues like operation not being permitted when trying to remove some folders in ~/Library after some application was uninstalled using AppCleaner.app, which I have used for years. It works 99% of the time, but sometimes I get errors that some files/folders in ~/Library can not be removed. If I try to "sudo rm -rf" that folder from Terminal, I get operation not permitted. So this did bring me to DiskUtility. I am running MBP 14 M1 Pro. As always when I get a new machine, the first thing I do is reformat SSD to Case Sensitive Encrypted from default Case Insensitive since that gives me issues with my source code compilation when developed between Mac and Linux. Here is my Disk Util. I do not get any warnings on any other partitions/sections under and including "Macintosh HD volume" at the top of the hierarchy. When I run FirstAid on the Data partition, I get the following warnings. Now I can run this repeatedly, and the same errors are produced. I can do a reboot in between running Disk Utilities, and the same warnings. I did boot to Safe Mode and run Disk Utility, and the same warnings. I contacted Apple support and have a case: 102125788648, but I was also instructed to create a case here. Here is my side story, why I can not use Time Machine. As a last resort, I was asked to reformat and reinstall. That is not an option for me at this point since restoring everything is a 1-2 day job. Now, I know there is a Time Machine, but on my two attempts in the past, backups created on brand new external Samsung 970 Pro SSD failed to restore. These two backups/restores were a few months apart. So on the second support call, it was suggested by support to back/restore using TimeMachine. After stating that I had a horror story on my first attempt a few months back, I was assured that the issue had been fixed and I should not have an issue. Oh well, same issue. After spending considerable time with support (a few folks) they noticed that the Time Machine folder structure was wrong and some intermediate folder was missing causing the issue. In both cases, I never heard anything back if it was addressed/fixed, except the support during the second case, assured me that it was fixed. That is why I did try to use Time Machine with him to back up while he was screensharing to make sure I did not do anything unusual. Still, restoration failed. So even Time Machine should make restoration painless, for it was pain, since on the first occasion I lost all the files. On second I could brow Time Machine folders in Terminal and pick files/folders from there. Took a long time. And to throw another strange case, I could only access them from Terminal under my wife's machine which is running an older Mac, but the new restored Mac I "was not able"! which is very weird. Both machines were at the time Intel machines. So I never attempted to use TimeMachine again on M1 Pro. So I hope everyone sees why I do not want to reformat and restore. Now, I have a feeling that most of my problems might be related to Case Sensitive reformated SSD. I can not go back to Case Insensitive (default), as I explained above. I am here to provide any information to help get this fixed. Any suggestions or anything to try? Robert
Replies
0
Boosts
0
Views
956
Activity
Oct ’23
No block-storage-device capability for development
Hi there! I know there was some update that allows the one to develop using driverKit without requesting entitlements for development. Unfortunately, it seems that block-storage-device capability is the only missed from list, so it can't be really added and used. Is it expected or a bug?
Replies
1
Boosts
0
Views
921
Activity
Feb ’23
How to access dmaaddress (Physical Address) in DriverKit?
I am trying to use IOUserBlockStorageDevice in DriverKit to simulate a fake device (Implementing a Ram Disk). Currently I'm confused on how to use the dmaaddress in the following interface virtual kern_return_t DoAsyncReadWrite (bool isRead, uint32_t requestID, uint64_t dmaAddr, uint64_t size, uint64_t lba, uint64_t numOfBlocks, IOUserStorageOptions options) = 0; According to https://github.com/briancabbott/macOS-system-projects/blob/19310aa5c7b7507408261a22a2e8f46f9d478a88/Resources/Code/apple-oss-distributions/IOStorageFamily/IOUserBlockStorageDevice_kext.cpp Before calling "DoAsyncReadWrite", kernel allocate a segment of physical memory by using "IODMAcommand::genIOVMSegments". This segment's physical address is pass to DoAsyncReadWrite as parameter "dmaAddr". To implement a correct ram disk, we need to "transform" this physical address to virtual so that we can "Read" or "Write" on this physical address. I tried to use "IOMemoryDescriptor" to access this dmaAddr. In IOKit, I belive I can use interface such as "withPhysicalAddress" to access the memory. However, such interface is not exist while using driverkit, all interface that I can use in DriverKit IOMemoryDescriptor is : -kern_return_t GetLength(uint64_t * returnLength) LOCALONLY; // apparently not this one -virtual kern_return_t CreateMapping( uint64_t options, uint64_t address, uint64_t offset, uint64_t length, uint64_t alignment, IOMemoryMap ** map); // Maybe this one with kIOMemoryFixedAddress option? // But I get Segment Fault while calling this with CreateMapping( kIOMemoryFixedAddress , dmaaddr, 0, size, 0, &map); // Or getting error return while calling CreateMapping with same paramters after IOBufferMemoryDescriptor::Create // Also, output iomemorymap is not used here, which is quiet strange. static kern_return_t CreateSubMemoryDescriptor(uint64_t memoryDescriptorCreateOptions, uint64_t offset, uint64_t length, IOMemoryDescriptor * ofDescriptor, IOMemoryDescriptor ** memory) attribute((availability(driverkit,introduced=20.0))); // Seems not this, it create “sub“ memory descriptor static kern_return_t CreateWithMemoryDescriptors(uint64_t memoryDescriptorCreateOptions, uint32_t withDescriptorsCount, IOMemoryDescriptor * const withDescriptors[32], IOMemoryDescriptor ** memory) attribute((availability(driverkit,introduced=20.0))); // Seems not this, it don’t take any dmaaddr as parameter. and a private function kern_return_t Map( uint64_t options, uint64_t address, uint64_t length, uint64_t alignment, uint64_t * returnAddress, uint64_t * returnLength) LOCALONLY; // Maybe this one? But the header file don’t show any description on this function and we are not sure what parameters should we pass. // Currently I've test Map( kIOMemoryFixedAddress , dmaaddr, size, 0, &returnAddress, &returnLength) but get error return. It seems that I've made some mistake on using IOMemoryDescriptor? How to correct access a dmaaddress? I've also tried class "IODMACommand", but also get unexpected behavior. Another question is how to read / write buffer after I create correct mapping. While implementing kext, IOMemoryDescriptor can use "readBytes" or "writeBytes" to read or write memory that IOMemoryDescriptor maps to. However, DriverKit don’t have interface of "readBytes" or "writeBytes". Maybe I can directly access buffer by casting the IOMemoryDescriptor::Map "returnAddress" to void? (I haven't tried it yet cause "Map" always failed now QQ) Thanks for everyone's help.
Replies
2
Boosts
1
Views
2.4k
Activity
Feb ’23
How to correctly create IOUserBlockStorageDevice through iouserclient?
I'm currently use IOUserBlockStorageDevice to simulate a ram disk. To simulate a pluggable ramdisk that can commute, I would like to use a hierarcy architecture. However, something strange happened while I'm using hierarcy architecture. The hierarcy architecture might shows as following in ioreg ... +-o IOUserResources <class IOUserResources, id 0x10000011b, registered, matched, active, busy 0 (571 ms), retain 9> | +-o IOUserDockChannelSerial <class IOUserService, id 0x10000040c, registered, matched, active, busy 0 (0 ms), retain 8> | +-o MyService <class IOUserService, id 0x10000040d, registered, matched, active, busy 0 (2 ms), retain 9> | +-o MyUserClient <class IOUserUserClient, id 0x100000760, registered, matched, active, busy 0 (2 ms), retain 9> | +-o MyDevice <class IOUserBlockStorageDevice, id 0x100000762, registered, matched, active, busy 0 (2 ms), retain 8> | +-o IOBlockStorageDriver <class IOBlockStorageDriver, id 0x100000763, registered, matched, active, busy 0 (1 ms), retain 8> | +-o Testing Media <class IOMedia, id 0x100000764, registered, matched, active, busy 0 (1 ms), retain 9> | +-o IOMediaBSDClient <class IOMediaBSDClient, id 0x100000765, registered, matched, active, busy 0 (0 ms), retain 6> +-o IOUserServer(com.apple.IOUserDockChannelSerial-0x10000040c) <class IOUserServer, id 0x100000472, registered, matched, active, busy 0 (0 ms), retain 11> +-o IOUserServer(com.example.apple-samplecode.dext-to-user-client.driver-0x10000040d) <class IOUserServer, id 0x100000474, registered, matched, active, busy 0 (0 ms), retain 13> MyService is the loaded dext, which create an UserClient while a client connect. MyUserClient has two interface: adddevice / remove which will add or remove a MyDevice instance. MyDevice is the IOUserBlockStorageDevice create by MyuserClient. I'm using the following plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>$(DEVELOPMENT_LANGUAGE)</string> <key>CFBundleExecutable</key> <string>$(EXECUTABLE_NAME)</string> <key>CFBundleIdentifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>$(PRODUCT_NAME)</string> <key>CFBundlePackageType</key> <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleVersion</key> <string>1</string> <key>IOKitPersonalities</key> <dict> <key>testDevice</key> <dict> <key>CFBundleIdentifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleIdentifierKernel</key> <string>com.apple.kpi.iokit</string> <key>IOClass</key> <string>IOUserService</string> <key>IOMatchCategory</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>IOProviderClass</key> <string>IOUserResources</string> <key>IOResourceMatch</key> <string>IOKit</string> <key>IOUserClass</key> <string>MyService</string> <key>IOUserServerName</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>UserClientProperties</key> <dict> <key>MyDeviceProperties</key> <dict> <key>CFBundleIdentifierKernel</key> <string>com.apple.iokit.IOStorageFamily</string> <key>IOClass</key> <string>IOUserBlockStorageDevice</string> <key>IOUserClass</key> <string>MyDevice</string> </dict> <key>IOClass</key> <string>IOUserUserClient</string> <key>IOUserClass</key> <string>MyUserClient</string> </dict> </dict> </dict> <key>OSBundleUsageDescription</key> <string></string> </dict> </plist> and MyDevice is create by "auto kr = Create(this, "MyDeviceProperties", &client);" in MyUserClient. To make sure the flow of MyDevice, I add an simple log (inside xxx function) while entering each function implement. Following is the system log after adddevice: === ExternalMethod AddDevice === 2022-10-21 12:08:20.424783+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient ccc Inside ExternalMethod!!!!! 2022-10-21 12:08:20.424803+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient ExternalMethodType_AddDevice 2022-10-21 12:08:20.424812+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient NewDevice 2022-10-21 12:08:20.424847+0800 0xcd3cd Default 0x0 0 0 kernel: (IOStorageFamily) INFO virtual bool IOUserBlockStorageDevice::init(OSDictionary *): Allocate resources 2022-10-21 12:08:20.425059+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice init..... 2022-10-21 12:08:20.425145+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice init done 2022-10-21 12:08:20.425152+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Start 2022-10-21 12:08:20.425158+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) IOUserBlockStorageDevice::Start() 2022-10-21 12:08:20.425201+0800 0xcd3cd Default 0x0 0 0 kernel: (IOStorageFamily) INFO kern_return_t IOUserBlockStorageDevice::RegisterDext_Impl(): Registering dext 2022-10-21 12:08:20.425212+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Reg service 2022-10-21 12:08:20.425270+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Start() - Finished. 2022-10-21 12:08:20.425281+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient NewDevice done 2022-10-21 12:08:20.425598+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside ReportRemovability 2022-10-21 12:08:20.425852+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside ReportWriteProtection 2022-10-21 12:08:20.425916+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside GetVendorString 2022-10-21 12:08:20.426022+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside GetProductString <log end, device stuch here> The IOUserBlockStorageDevice stuck after calling GetProductString, not called GetDeviceParam, and the device size remains be zero in this case. I'm not sure why MyDevice stuck. Could anyone help for this case? I'll post some detailed test in reply.
Replies
1
Boosts
0
Views
1.7k
Activity
Nov ’22
IOS16 Browser: LocalStorage is cleared after writing data of more than ~2.5MB
IOS16 Safari: LocalStorage is cleared after writing data of more than ~2.5MB. After upgrading to IOS 16 we faced the problem of clearing data in localStorage.When we try to write data that size is more than ~2.5MB or all amounts of data more than ~2.5MB the LocalStorage is being cleared without any errors and warnings in Safari. I could not reproduce the problem in other browsers or platforms. Step to reproduce: Go to IOS 16 Safari Open any website try to write data more than ~2.5MB (the attached defineMaxSizeLs.js test script helps you to display the problem) check your localStorage Actual result: your localStorage is empty Expected result: your localStorage should be filled your data or it should be thrown an exception if the quota is exceeded Please consider the problem ASAP. Thank you in advance!
Replies
2
Boosts
1
Views
4.5k
Activity
Sep ’22