Advertisement
Guest User

mmio.cpp

a guest
Jul 14th, 2015
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.27 KB | None | 0 0
  1. /**----------------------------------------------------------------------------
  2.  *
  3.  *-----------------------------------------------------------------------------
  4.  * All rights reserved by Noh,Yonghwan (fixbrain@gmail.com, unsorted@msn.com)
  5.  *-----------------------------------------------------------------------------
  6.  *
  7. **---------------------------------------------------------------------------*/
  8.  
  9. // read
  10. // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366542(v=vs.85).aspx
  11.  
  12. #include "stdafx.h"
  13.  
  14. /**
  15.  * @brief
  16.  * @param  
  17.  * @see    
  18.  * @remarks
  19.  * @code       
  20.  * @endcode
  21.  * @return 
  22. **/
  23. bool read_file_using_memory_map()
  24. {
  25.     // current directory 를 구한다.
  26.     wchar_t *buf=NULL;
  27.     uint32_t buflen = 0;
  28.     buflen = GetCurrentDirectoryW(buflen, buf);
  29.     if (0 == buflen)
  30.     {
  31.         print("err ] GetCurrentDirectoryW() failed. gle = 0x%08x", GetLastError());
  32.         return false;
  33.     }
  34.  
  35.     buf = (PWSTR) malloc(sizeof(WCHAR) * buflen);
  36.     if (0 == GetCurrentDirectoryW(buflen, buf))
  37.     {
  38.         print("err ] GetCurrentDirectoryW() failed. gle = 0x%08x", GetLastError());
  39.         free(buf);
  40.         return false;
  41.     }
  42.  
  43.     // current dir \\ test.txt 파일명 생성
  44.     wchar_t file_name[260];
  45.     if (!SUCCEEDED(StringCbPrintfW(
  46.                             file_name,
  47.                             sizeof(file_name),
  48.                             L"%ws\\test.txt",
  49.                             buf)))
  50.     {  
  51.         print("err ] can not create file name");
  52.         free(buf);
  53.         return false;
  54.     }
  55.     free(buf); buf = NULL;
  56.  
  57.     if (true != is_file_existsW(file_name))
  58.     {
  59.         print("err ] no file exists. file = %ws", file_name);
  60.         return false;
  61.     }
  62.  
  63.     HANDLE file_handle = CreateFileW(
  64.                             (LPCWSTR)file_name,
  65.                             GENERIC_READ,
  66.                             NULL,
  67.                             NULL,
  68.                             OPEN_EXISTING,
  69.                             FILE_ATTRIBUTE_NORMAL,
  70.                             NULL
  71.                             );
  72.     if (INVALID_HANDLE_VALUE == file_handle)
  73.     {
  74.         print("err ] CreateFile(%ws) failed, gle = %u", file_name, GetLastError());
  75.         return false;
  76.     }
  77.  
  78.     // check file size
  79.     //
  80.     LARGE_INTEGER fileSize;
  81.     if (TRUE != GetFileSizeEx(file_handle, &fileSize))
  82.     {
  83.         print("err ] GetFileSizeEx(%ws) failed, gle = %u", file_name, GetLastError());
  84.         CloseHandle(file_handle);
  85.         return false;
  86.     }
  87.  
  88.     // [ WARN ]
  89.     //
  90.     // 4Gb 이상의 파일의 경우 MapViewOfFile()에서 오류가 나거나
  91.     // 파일 포인터 이동이 문제가 됨
  92.     // FilIoHelperClass 모듈을 이용해야 함
  93.     //
  94.     _ASSERTE(fileSize.HighPart == 0);
  95.     if (fileSize.HighPart > 0)
  96.     {
  97.         print("file size = %I64d (over 4GB) can not handle. use FileIoHelperClass",
  98.             fileSize.QuadPart);
  99.         CloseHandle(file_handle);
  100.         return false;
  101.     }
  102.  
  103.     DWORD file_size = (DWORD)fileSize.QuadPart;
  104.     HANDLE file_map = CreateFileMapping(
  105.                             file_handle,
  106.                             NULL,
  107.                             PAGE_READONLY,
  108.                             0,
  109.                             0,
  110.                             NULL
  111.                             );
  112.     if (NULL == file_map)
  113.     {
  114.         print("err ] CreateFileMapping(%ws) failed, gle = %u", file_name, GetLastError());
  115.         CloseHandle(file_handle);
  116.         return false;
  117.     }
  118.  
  119.     PCHAR file_view = (PCHAR) MapViewOfFile(
  120.                                     file_map,
  121.                                     FILE_MAP_READ,
  122.                                     0,
  123.                                     0,
  124.                                     0
  125.                                     );
  126.     if(file_view == NULL)
  127.     {
  128.         print("err ] MapViewOfFile(%ws) failed, gle = %u", file_name, GetLastError());
  129.        
  130.         CloseHandle(file_map);
  131.         CloseHandle(file_handle);
  132.         return false;
  133.     }  
  134.  
  135.     // do some io
  136.     char a = file_view[0];  // 0x d9
  137.     char b = file_view[1];  // 0xb3
  138.  
  139.  
  140.  
  141.     // close all
  142.     UnmapViewOfFile(file_view);
  143.     CloseHandle(file_map);
  144.     CloseHandle(file_handle);
  145.     return true;
  146. }
  147.  
  148.  
  149. /**
  150.  * @brief
  151.  * @param  
  152.  * @see    
  153.  * @remarks
  154.  * @code       
  155.  * @endcode
  156.  * @return 
  157. **/
  158. bool create_very_big_file(_In_ const wchar_t* file_path, _In_ uint32_t size_in_mb)
  159. {
  160.     _ASSERTE(NULL != file_path);
  161.     if (NULL == file_path) return false;
  162.  
  163.     if (is_file_existsW(file_path))
  164.     {
  165.         ::DeleteFileW(file_path);
  166.     }
  167.  
  168.     // create very big file
  169.     HANDLE file_handle = CreateFile(
  170.                             file_path,
  171.                             GENERIC_WRITE,
  172.                             FILE_SHARE_READ,
  173.                             NULL,
  174.                             CREATE_NEW,
  175.                             FILE_ATTRIBUTE_NORMAL,
  176.                             NULL
  177.                             );
  178.     if (INVALID_HANDLE_VALUE == file_handle)
  179.     {
  180.         print("err ] CreateFile( %ws ) failed. gle = %u", file_path, GetLastError());
  181.         return false;
  182.     }
  183.  
  184.     LARGE_INTEGER file_size = {0};
  185.     //file_size.LowPart = 0;
  186.     //file_size.HighPart = 1;
  187.     file_size.QuadPart = (1024 * 1024) * size_in_mb;
  188.  
  189.     if (!SetFilePointerEx(file_handle, file_size, NULL, FILE_BEGIN))
  190.     {
  191.         print("err ] SetFilePointerEx() failed. gle = %u", GetLastError());
  192.  
  193.         CloseHandle(file_handle);
  194.         return false;
  195.     }
  196.  
  197.     SetEndOfFile(file_handle);
  198.     CloseHandle(file_handle);
  199.     return true;
  200. }
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213. /**
  214.  * @brief  
  215.  * @param  
  216.  * @see    
  217.  * @remarks
  218.  * @code       
  219.  * @endcode
  220.  * @return 
  221. **/
  222. typedef struct map_context
  223. {
  224.     HANDLE  handle;
  225.     DWORD   size;
  226.     HANDLE  map;
  227.     PCHAR   view;
  228. }* pmap_context;
  229.  
  230. pmap_context open_map_context(_In_ const wchar_t* file_path)
  231. {
  232.     _ASSERTE(NULL != file_path);
  233.     if (NULL == file_path) return false;
  234.     if (!is_file_existsW(file_path)) return false;;
  235.  
  236.     pmap_context ctx = (pmap_context)malloc(sizeof(map_context));
  237.     RtlZeroMemory(ctx, sizeof(map_context));
  238.  
  239.     bool ret = false;
  240.  
  241. #pragma warning(disable: 4127)
  242.     do
  243.     {
  244.         ctx->handle = CreateFileW(
  245.                             (LPCWSTR)file_path,
  246.                             GENERIC_READ,
  247.                             NULL,
  248.                             NULL,
  249.                             OPEN_EXISTING,
  250.                             FILE_ATTRIBUTE_NORMAL,
  251.                             NULL
  252.                             );
  253.         if (INVALID_HANDLE_VALUE == ctx->handle)
  254.         {
  255.             print("err ] CreateFile( %ws ) failed. gle = %u", file_path, GetLastError());
  256.             break;
  257.         }
  258.  
  259.         // check file size
  260.         //
  261.         LARGE_INTEGER fileSize;
  262.         if (TRUE != GetFileSizeEx(ctx->handle, &fileSize))
  263.         {
  264.             print("err ] GetFileSizeEx( %ws ) failed. gle = %u", file_path, GetLastError());
  265.             break;
  266.         }
  267.  
  268.         // [ WARN ]
  269.         //
  270.         // 4Gb 이상의 파일의 경우 MapViewOfFile()에서 오류가 나거나
  271.         // 파일 포인터 이동이 문제가 됨
  272.         // FilIoHelperClass 모듈을 이용해야 함
  273.         //
  274.         _ASSERTE(fileSize.HighPart == 0);
  275.         if (fileSize.HighPart > 0)
  276.         {
  277.             print("err ] file is too large to map. file = %ws, size = %llu", file_path, fileSize.QuadPart);
  278.             break;
  279.         }
  280.  
  281.         ctx->size = (DWORD)fileSize.QuadPart;
  282.         ctx->map = CreateFileMapping(
  283.                                 ctx->handle,
  284.                                 NULL,
  285.                                 PAGE_READONLY,
  286.                                 0,
  287.                                 0,
  288.                                 NULL
  289.                                 );
  290.         if (NULL == ctx->map)
  291.         {
  292.             print("err ] CreateFileMapping( %ws ) failed. gle = %u", file_path, GetLastError());
  293.             break;
  294.         }
  295.  
  296.         ctx->view = (PCHAR) MapViewOfFile(
  297.                                 ctx->map,
  298.                                 FILE_MAP_READ,
  299.                                 0,
  300.                                 0,
  301.                                 0
  302.                                 );
  303.         if(ctx->view == NULL)
  304.         {
  305.             print("err ] MapViewOfFile( %ws ) failed. gle = %u", file_path, GetLastError());
  306.             break;
  307.         }    
  308.        
  309.         ret = true;
  310.     } while (FALSE);
  311. #pragma warning(default: 4127)
  312.  
  313.     if (!ret)
  314.     {
  315.         if (NULL!= ctx->view) UnmapViewOfFile(ctx->view);
  316.         if (NULL!= ctx->map) CloseHandle(ctx->map);
  317.         if (INVALID_HANDLE_VALUE != ctx->handle) CloseHandle(ctx->handle);        
  318.        
  319.         free(ctx); ctx = NULL;
  320.     }
  321.  
  322.     return ctx;
  323. }
  324.  
  325. /**
  326.  * @brief  
  327.  * @param  
  328.  * @see    
  329.  * @remarks
  330.  * @code       
  331.  * @endcode
  332.  * @return 
  333. **/
  334. pmap_context create_map_context(_In_ const wchar_t* file_path, _In_ uint32_t file_size)
  335. {
  336.     _ASSERTE(NULL != file_path);
  337.     if (NULL == file_path) return false;
  338.     if (is_file_existsW(file_path))
  339.     {
  340.         DeleteFileW(file_path);
  341.     }
  342.  
  343.     pmap_context ctx = (pmap_context)malloc(sizeof(map_context));
  344.     RtlZeroMemory(ctx, sizeof(map_context));
  345.  
  346.     bool ret = false;
  347.  
  348. #pragma warning(disable: 4127)
  349.     do
  350.     {
  351.         ctx->handle = CreateFileW(
  352.                             (LPCWSTR)file_path,
  353.                             GENERIC_READ | GENERIC_WRITE,
  354.                             NULL,
  355.                             NULL,
  356.                             CREATE_NEW,
  357.                             FILE_ATTRIBUTE_NORMAL,
  358.                             NULL
  359.                             );
  360.         if (INVALID_HANDLE_VALUE == ctx->handle)
  361.         {
  362.             print("err ] CreateFile( %ws ) failed. gle = %u", file_path, GetLastError());
  363.             break;
  364.         }
  365.  
  366.         ctx->size = file_size;
  367.         ctx->map = CreateFileMapping(
  368.                             ctx->handle,
  369.                             NULL,
  370.                             PAGE_READWRITE,
  371.                             0,
  372.                             ctx->size,
  373.                             NULL
  374.                             );
  375.         if (NULL == ctx->map)
  376.         {
  377.             print("err ] CreateFileMapping( %ws ) failed. gle = %u", file_path, GetLastError());
  378.             break;
  379.         }
  380.  
  381.         ctx->view = (PCHAR) MapViewOfFile(
  382.                             ctx->map,
  383.                             FILE_MAP_WRITE,
  384.                             0,
  385.                             0,
  386.                             ctx->size
  387.                             );
  388.         if(ctx->view == NULL)
  389.         {
  390.             print("err ] MapViewOfFile( %ws ) failed. gle = %u", file_path, GetLastError());
  391.             break;
  392.         }    
  393.        
  394.         ret = true;
  395.     } while (FALSE);
  396. #pragma warning(default: 4127)
  397.  
  398.     if (!ret)
  399.     {
  400.         if (NULL!= ctx->view) UnmapViewOfFile(ctx->view);
  401.         if (NULL!= ctx->map) CloseHandle(ctx->map);
  402.         if (INVALID_HANDLE_VALUE != ctx->handle) CloseHandle(ctx->handle);        
  403.        
  404.         free(ctx); ctx = NULL;
  405.     }
  406.  
  407.     return ctx;
  408. }
  409.  
  410. /**
  411.  * @brief  
  412.  * @param  
  413.  * @see    
  414.  * @remarks
  415.  * @code       
  416.  * @endcode
  417.  * @return 
  418. **/
  419. void close_map_context(_In_ pmap_context ctx)
  420. {
  421.     if (NULL != ctx)
  422.     {
  423.         if (NULL!= ctx->view) UnmapViewOfFile(ctx->view);
  424.         if (NULL!= ctx->map) CloseHandle(ctx->map);
  425.         if (INVALID_HANDLE_VALUE != ctx->handle) CloseHandle(ctx->handle);
  426.         free(ctx);
  427.     }
  428. }
  429.  
  430.  
  431. /**
  432.  * @brief  
  433.  * @param  
  434.  * @see    
  435.  * @remarks
  436.  * @code       
  437.  * @endcode
  438.  * @return 
  439. **/
  440. bool
  441. file_copy_using_memory_map(
  442.     _In_ const wchar_t* src_file,
  443.     _In_ const wchar_t* dst_file
  444.     )
  445. {
  446.     _ASSERTE(NULL != src_file);
  447.     _ASSERTE(NULL != dst_file);
  448.     if (NULL == src_file || NULL == dst_file) return false;
  449.  
  450.     if(!is_file_existsW(src_file))
  451.     {
  452.         print("err ] no src file = %ws", src_file);
  453.         return false;
  454.     }
  455.  
  456.     if (is_file_existsW(dst_file))
  457.     {
  458.         DeleteFileW(dst_file);
  459.     }
  460.  
  461.     // map src, dst file
  462.     pmap_context src_ctx = open_map_context(src_file);
  463.     pmap_context dst_ctx = create_map_context(dst_file, src_ctx->size);
  464.     if (NULL == src_ctx || NULL == dst_ctx)
  465.     {
  466.         print("err ] open_map_context() failed.");
  467.         close_map_context(src_ctx);
  468.         close_map_context(dst_ctx);
  469.         return false;
  470.     }
  471.  
  472.     // copy src to dst by mmio
  473.     for (uint32_t i = 0; i < src_ctx->size; ++i)
  474.     {
  475.         dst_ctx->view[i] = src_ctx->view[i];
  476.     }
  477.  
  478.     return true;
  479. }
  480.  
  481. /**
  482.  * @brief  
  483.  * @param  
  484.  * @see    
  485.  * @remarks
  486.  * @code       
  487.  * @endcode
  488.  * @return 
  489. **/
  490. bool
  491. file_copy_using_read_write(
  492.     _In_ const wchar_t* src_file,
  493.     _In_ const wchar_t* dst_file
  494.     )
  495. {
  496.     _ASSERTE(NULL != src_file);
  497.     _ASSERTE(NULL != dst_file);
  498.     if (NULL == src_file || NULL == dst_file) return false;
  499.  
  500.     if(!is_file_existsW(src_file))
  501.     {
  502.         print("err ] no src file = %ws", src_file);
  503.         return false;
  504.     }
  505.  
  506.     if (is_file_existsW(dst_file))
  507.     {
  508.         DeleteFileW(dst_file);
  509.     }
  510.  
  511.     // open src file with READ mode
  512.     HANDLE src_handle = CreateFileW(
  513.                             src_file,
  514.                             GENERIC_READ,
  515.                             FILE_SHARE_READ,
  516.                             NULL,
  517.                             OPEN_EXISTING,
  518.                             FILE_ATTRIBUTE_NORMAL,
  519.                             NULL
  520.                             );
  521.     if (INVALID_HANDLE_VALUE == src_handle)
  522.     {
  523.         print("err ] CreateFile( %ws ) failed. gle = %u", src_file, GetLastError());
  524.         return false;
  525.     }
  526.  
  527.     // open dst file with WRITE mode
  528.     HANDLE dst_handle = CreateFileW(
  529.                             dst_file,
  530.                             GENERIC_WRITE,
  531.                             FILE_SHARE_READ,
  532.                             NULL,
  533.                             CREATE_NEW,
  534.                             FILE_ATTRIBUTE_NORMAL,
  535.                             NULL
  536.                             );
  537.     if (INVALID_HANDLE_VALUE == dst_handle)
  538.     {
  539.         print("err ] CreateFile( %ws ) failed. gle = %u", dst_file, GetLastError());
  540.  
  541.         CloseHandle(src_handle);
  542.         return false;
  543.     }
  544.  
  545.     // file copy
  546.     bool ret = false;
  547.     char buf[4096] = {0};
  548.     DWORD bytes_written = 0;
  549.     DWORD bytes_read = 0;
  550.  
  551.     do
  552.     {
  553.         // read from src
  554.         if (!ReadFile(src_handle, buf, sizeof(buf), &bytes_read, NULL))
  555.         {
  556.             print("err ] ReadFile( src_handle ) failed. gle = %u", GetLastError());
  557.             break;
  558.         }
  559.         else
  560.         {
  561.             // please read
  562.             // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365690(v=vs.85).aspx
  563.             if (0 == bytes_read)
  564.             {
  565.                 ret = true;
  566.                 break;
  567.             }
  568.         }
  569.        
  570.         // write to dst
  571.         if (!WriteFile(dst_handle, buf, sizeof(buf), &bytes_written, NULL))
  572.         {
  573.             print("err ] WriteFile( dst_handle ) failed. gle = %u", GetLastError());
  574.             break;
  575.         }
  576.     } while (true);
  577.  
  578.  
  579.     CloseHandle(src_handle);
  580.     CloseHandle(dst_handle);
  581.     return ret;
  582. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement