locked
How to Create/Save file in Metro Dynamic-Link library

    Question

  • Hi all:

    My Metro App call a dynamic-link library.

    I want to save file in the dynamic-link library(dll)

    I found createfile2() can be used in Metro/Desktop platform.

    I have looked up the Metro sample about CreateFile2()

    ==============================================

     CREATEFILE2_EXTENDED_PARAMETERS extendedParams = {0};
        extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
        extendedParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
        extendedParams.dwFileFlags = FILE_FLAG_SEQUENTIAL_SCAN;
        extendedParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
        extendedParams.lpSecurityAttributes = nullptr;
        extendedParams.hTemplateFile = nullptr;

     Platform::String^ m_locationPath;
     m_locationPath = Platform::String::Concat(path, "\\");

        //Wrappers::FileHandle file(
      ScopedHandle file(
            CreateFile2(
                Platform::String::Concat(m_locationPath, filename)->Data(),
                GENERIC_READ,
                0,
                OPEN_EXISTING,
                &extendedParams
                )

    ========================================================

    But when I use createfile2(), every time file is not valid.

    (dll can not use Platform::)

    (I have set the Capabilities for the picture library)

    I try my code(in dll):

     ScopedHandle hFile( CreateFile2( L"C:\\Users\\asus-Hardi\\Pictures\\log.txt", GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) );

     if ( !hFile.IsValid() )
        {
            return;
        }

    Is there any way to save file in dll?

    Thanks



    Friday, April 06, 2012 6:40 AM

Answers

  • To elaborate on Raptors answer, Metro style app file api calls go through a file broker which controls access to the file system. The Win32 and CRT file api's don't know about this broker so can't get access to the file system. Setting the app capabilites tells the broker that the app has access to specific files but doesn't enable Win32 access.

    You can call the StorageFile api from native code - i.e. code not compiled with /ZW. Here's a sample that uses the Windows Runtime Library (WRL) template library. This is just Win32 DLL project type:

    using namespace Microsoft::WRL;
    using namespace Microsoft::WRL::Wrappers;
    using namespace ABI::Windows::Storage;
    using namespace ABI::Windows::Foundation;
    
    // This is an example of an exported variable
    TARGETDLL_API int nTargetDLL=0;
    
    // This is an example of an exported function.
    TARGETDLL_API void fnTargetDLL(void)
    {
    	HRESULT hr;
    
    	HString hstrKnownFolders;
    	hstrKnownFolders.Set(RuntimeClass_Windows_Storage_KnownFolders);
    
    	// Get the Activation Factory
    	ComPtr<IActivationFactory> pKnownFoldersActivationFactory;
    	hr = GetActivationFactory(hstrKnownFolders.Get(), &pKnownFoldersActivationFactory);
    	if (FAILED(hr))
    	{
    		::Microsoft::WRL::Details::RaiseException(hr);
    	}
    
    	// QI for KnownFolders
    	ComPtr<IKnownFoldersStatics> pKnownFolders;
    	hr = pKnownFoldersActivationFactory.As(&pKnownFolders);
    	if (FAILED(hr))
    	{
    		::Microsoft::WRL::Details::RaiseException(hr);
    	}
    
    	// Get the Pictures library folder
    	ComPtr<IStorageFolder> pStorageFolder;
    	hr = pKnownFolders->get_PicturesLibrary(&pStorageFolder);
    	if (FAILED(hr))
    	{
    		::Microsoft::WRL::Details::RaiseException(hr);
    	}
    
    
    	HString hstrFileName;
    	hstrFileName.Set(L"sample.txt");
    
    	// Call CreteFileAsync
    	__FIAsyncOperation_1_Windows__CStorage__CStorageFile_t * operation;    
    	hr = pStorageFolder->CreateFileAsync(hstrFileName.Get(),
    		CreationCollisionOption::CreationCollisionOption_ReplaceExisting,
    		&operation);
    	if (FAILED(hr))
    	{
    		::Microsoft::WRL::Details::RaiseException(hr);
    	}
    }

    This is a Win32 Application Wizard project with project type set to DLL and "Export Symbols" checked.

    Link the Metro style project with the LIB file and include the DLL in your app package. Now you're going through the file broker and if the capabilites are set you'll be able to create a file the Pictures folder.

    -Steve

    • Proposed as answer by Raptor K Tuesday, April 10, 2012 1:14 AM
    • Marked as answer by Hardi_Liang Tuesday, April 10, 2012 7:27 AM
    • Unmarked as answer by Hardi_Liang Tuesday, April 10, 2012 11:42 AM
    • Marked as answer by Hardi_Liang Wednesday, April 11, 2012 3:43 AM
    Tuesday, April 10, 2012 12:31 AM
    Moderator

All replies

  • Why not use StorageFile class instead of win32 API

    http://msdn.microsoft.com/en-us/library/windows/desktop/windows.storage.storagefile.aspx


    NEU_ShieldEdge

    Monday, April 09, 2012 8:04 AM
  • Dear Luke:

    Do you know how to use metro API like StorageFile class in dynamic-link library(with dllmain DLL)?

    Thanks,

    Hardi

    Monday, April 09, 2012 10:57 AM
  • The fopen in C also works, no async, no CX extension, for small files, no problem!

    You may not have accessing right to that directory. You need to set File Type Association declaration in the app manifest .

    And CreateFile2/fopen cannot access library directories directly. You need a FilePicker.

    WinRT DLL can use Platform:: too.





    • Edited by Raptor K Monday, April 09, 2012 3:14 PM
    Monday, April 09, 2012 2:59 PM
  • To elaborate on Raptors answer, Metro style app file api calls go through a file broker which controls access to the file system. The Win32 and CRT file api's don't know about this broker so can't get access to the file system. Setting the app capabilites tells the broker that the app has access to specific files but doesn't enable Win32 access.

    You can call the StorageFile api from native code - i.e. code not compiled with /ZW. Here's a sample that uses the Windows Runtime Library (WRL) template library. This is just Win32 DLL project type:

    using namespace Microsoft::WRL;
    using namespace Microsoft::WRL::Wrappers;
    using namespace ABI::Windows::Storage;
    using namespace ABI::Windows::Foundation;
    
    // This is an example of an exported variable
    TARGETDLL_API int nTargetDLL=0;
    
    // This is an example of an exported function.
    TARGETDLL_API void fnTargetDLL(void)
    {
    	HRESULT hr;
    
    	HString hstrKnownFolders;
    	hstrKnownFolders.Set(RuntimeClass_Windows_Storage_KnownFolders);
    
    	// Get the Activation Factory
    	ComPtr<IActivationFactory> pKnownFoldersActivationFactory;
    	hr = GetActivationFactory(hstrKnownFolders.Get(), &pKnownFoldersActivationFactory);
    	if (FAILED(hr))
    	{
    		::Microsoft::WRL::Details::RaiseException(hr);
    	}
    
    	// QI for KnownFolders
    	ComPtr<IKnownFoldersStatics> pKnownFolders;
    	hr = pKnownFoldersActivationFactory.As(&pKnownFolders);
    	if (FAILED(hr))
    	{
    		::Microsoft::WRL::Details::RaiseException(hr);
    	}
    
    	// Get the Pictures library folder
    	ComPtr<IStorageFolder> pStorageFolder;
    	hr = pKnownFolders->get_PicturesLibrary(&pStorageFolder);
    	if (FAILED(hr))
    	{
    		::Microsoft::WRL::Details::RaiseException(hr);
    	}
    
    
    	HString hstrFileName;
    	hstrFileName.Set(L"sample.txt");
    
    	// Call CreteFileAsync
    	__FIAsyncOperation_1_Windows__CStorage__CStorageFile_t * operation;    
    	hr = pStorageFolder->CreateFileAsync(hstrFileName.Get(),
    		CreationCollisionOption::CreationCollisionOption_ReplaceExisting,
    		&operation);
    	if (FAILED(hr))
    	{
    		::Microsoft::WRL::Details::RaiseException(hr);
    	}
    }

    This is a Win32 Application Wizard project with project type set to DLL and "Export Symbols" checked.

    Link the Metro style project with the LIB file and include the DLL in your app package. Now you're going through the file broker and if the capabilites are set you'll be able to create a file the Pictures folder.

    -Steve

    • Proposed as answer by Raptor K Tuesday, April 10, 2012 1:14 AM
    • Marked as answer by Hardi_Liang Tuesday, April 10, 2012 7:27 AM
    • Unmarked as answer by Hardi_Liang Tuesday, April 10, 2012 11:42 AM
    • Marked as answer by Hardi_Liang Wednesday, April 11, 2012 3:43 AM
    Tuesday, April 10, 2012 12:31 AM
    Moderator
  • As far as I know, Win32 and CRT can access to InstalledLocation and ApplicationData Folder with full DOS path,  correct?

    C++ DX11

    Tuesday, April 10, 2012 1:24 AM
  • Correct. Your app will have read access to its InstalledLocation and read/write access to its Application Data folder. It doesn't need to go through the broker to access these locations.

    The original question asked by Hardi_Liang was about the Pictures library. Even with the Pictures Library capability set the app doesn't have direct access to the Pictures Library. As Steve said, the capability allows the broker to access the library on the app's behalf.

    Setting the file type association is needed for brokered access to the general purpose Documents Library. It is not needed for the special purpose Libraries (Pictures, Music, Video) and is not relevant for unbrokered access.

    --Rob


    Tuesday, April 10, 2012 1:58 AM
    Owner
  • Can someone elaborate on this sample code?  How do I know when the CreateFileAsync is completed?  After the file is created, I want to:

    • Open it Async, then
    • Write to it Async, then 
    • Close the file

    For my purposes, I have to use Native code ( not compiled with /ZW)

    thanks,
    hrp

    Tuesday, June 05, 2012 5:39 PM