none
UWP: write file to disk using the simple and fast PInvoke calls CreateFile and WriteFile RRS feed

  • Question

  • We have an unmanaged memory C++ dll that generates video data. The user interface is in UWP VB. I need to write the video data to the disk. The user gives the location to write from a file picker and this path and file name is passed to the dll. Using CreateFile and WriteFile the data will be written to disk.

    This is the VB code

    <DllImport("mycplus.dll", CallingConvention:=CallingConvention.StdCall)>
    Public Function MainFrozen(ByVal EvF() As UInteger) As UInteger
    End Function
    
    
    Private Async Sub btnSaveAs_Click(sender As Object, e As RoutedEventArgs) Handles btnSaveAs.Click
        Dim savePicker = New Windows.Storage.Pickers.FileSavePicker()
        savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary
        savePicker.FileTypeChoices.Add("Video Files", New List(Of String)() From {".bin"})
        savePicker.SuggestedFileName = gVideoFileName
        Dim file As Windows.Storage.StorageFile = Await savePicker.PickSaveFileAsync()
    
        If file IsNot Nothing Then
            Dim fileName As String = file.Path
            Dim d(0 To 15) As UInt32
    
            d(0) = VIDEO_FILE_WRITE
            d(1) = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(fileName)
            d(2) = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(gAuthorName)
            d(3) = gReserved
    
            d(8) = MainFrozen(d)
        Else
            'txtDeubg.Text = "Operation cancelled."
        End If
    End Sub

    And the following is the C++ code

    extern "C" __declspec (dllexport) ULONG __stdcall MainFrozen(PULONG ptrEv)
    {
        ULONG eve = ptrEv[0];
    
        switch (eve)
        {
        case VIDEO_FILE_WRITE:
            SaveScanVideosToFile((LPCSTR)ptrEv[1], (LPCSTR)ptrEv[2], ptrEv[3]);
            break;
        }
        return 0;
    }
    
    
    ULONG SaveScanVideosToFile(LPCSTR   lpFileName, 
                                LPCSTR  lpAuthorName,
                                ULONG   reserved)
    {
    
        HANDLE hFile;
        ULONG bytesWritten;
        ULONG n;
    
        hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL,
            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    
        for (n=0; n<gScanVideoCnt; n++)
        {
            WriteFile(hFile, ScanVideos[n].pImg->Bcine.pCineMem, SCAN_VIDEO_MEM_SIZ, &bytesWritten, NULL);
            WriteFile(hFile, ScanVideos[n].pImg, sizeof(IMG_TYPE), &bytesWritten, NULL);
        }
        CloseHandle(hFile);
        return 0;
    }

    The problem is I am unable to write to any location other than: Windows.Storage.ApplicationData.Current.LocalFolder I.e C:\Users\ravi\AppData\Local\Packages\2d6e339b-614b-4161-8c7d-3570f07fc01f_2ygbv2t9jdb9y\LocalState\

    At other locations, CreateFile fails with access denied. However using the .net file functions I am able to write other test files to almost all locations in my PC in the latest creators edition of win10, which is most welcome and heartening.

    The question is: what security attributes should be set so that CreateFile will succeed and write to all location like the native .net file functions do?

    There could be workarounds like marshal the entire data to managed memory or writing the file to the ApplicationData.Current.LocalFolder and then moving it using vb.net calls. But nothing like making CreateFile succeed.

    PS: Our app is a side loaded one for enterprise use only and we do not mind if it fails windows stores test. (our customers are trusting us from “windows NT” days :-)

    Sibi

    Sunday, October 15, 2017 7:16 PM

Answers

All replies