Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

How do I copy an EFS encryted File to a USB drive that I cannot decrypt

Posted on 2010-08-22
5
Medium Priority
?
1,046 Views
Last Modified: 2012-05-10
I have 3 or 4 users a month that for one reason or another cannot boot their XP OS on their HD and need it to be re-imaged or replaced.  I would like to boot to WINPE, copy the files to USB drive, re-format or replace the HD, then copy the files back.  Some files are EFS Encrypted and the keys can be easily recovered from Active Directory after the HD is reformated and the files copied back to the HD.  I have tried the API's CopyFile and CopyFileEx but neither seem to be able to just copy the file without first decrypting it.  I do not want to decrypt the file while it is stored on the USB drive as the file may contain sensitive information and it is safer just to keep it encrypted while the OS is repaired. ImageX.exe can perform this task and I currently use it for this purpose by copying the files into a WIM file then onto USB.  The problem with imageX.exe is that I would rather just perform the raw copy within my VB6 code and retain a more granular control over which files get copied and which get left behind.
0
Comment
Question by:Cefer
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 33497147
You have to use the following function to copy/backup encrypted files.

OpenEncryptedFileRaw Function
http://msdn.microsoft.com/en-us/library/aa365429(v=VS.85).aspx
ReadEncryptedFileRaw Function
http://msdn.microsoft.com/en-us/library/aa365466(v=VS.85).aspx

WriteEncryptedFileRaw Function
http://msdn.microsoft.com/en-us/library/aa365746(v=VS.85).aspx 
CloseEncryptedFileRaw Function
http://msdn.microsoft.com/en-us/library/aa363839(v=VS.85).aspx

 
0
 

Author Comment

by:Cefer
ID: 33502203
eql1044, you are correct that the above C functions are the basis for copying encrypted files.  I also see that you provided an excelent VB.Net solution here:  http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_25235488.html .  My need to use VB6 is related to using this tool in WinPE.  I have the VB6 runtimes working in WinPE but not the VS .Net runtimes.  I have VB6 code to use FindFirstFile and FindNextFile that finds and copies files to the USB drive that match my filter but it fails to copy encrypted files.  To make a tool work in more situations I need to add the copy EncryptedFileRaw functionality.  I have searched the well of Google for any examples of this in VB6 but only found the Declare Function Statements.

Declare Function OpenEncryptedFileRaw Lib "advapi32" Alias "OpenEncryptedFileRawA" (ByVal lpFileName As String, ByVal ulFlags As Long, pvContext As Any) As Long
Declare Function ReadEncryptedFileRaw Lib "advapi32" (ByRef pfExportCallback As PFE_EXPORT_FUNC, pvCallbackContext As Any, pvContext As Any) As Long
Declare Function WriteEncryptedFileRaw Lib "advapi32.dll" (ByRef pfImportCallback As PFE_IMPORT_FUNC, pvCallbackContext As Any, pvContext As Any) As Long
Declare Sub CloseEncryptedFileRaw Lib "advapi32" (pvContext As Any)

My conversion skills from C to VB6 are not strong enough to put the right pieces together.
0
 
LVL 29

Accepted Solution

by:
nffvrxqgrcfqvvc earned 2000 total points
ID: 33502389
If your not the owner or on the list for the encrypted files you will have to enable SeBackupPrivilege so you can bypass the security on the file.
I won't go much into that because I explained alot of this in the question you already have found but want to give you a heads up briefly.
I have written a very simple example that would help you use the encrypted API's
(add the code) In a module named : efsbackup.bas
The Backup() method will store the raw content in file. When you need to Restore() the file point it to that raw backup and use the Restore() method.
Usage://
Backup "c:\test\dotnetfx.exe", "c:\test\dotnetfx.exe.efs"
Restore "c:\test\dotnetfx.exe.efs", "c:\test\dotnetfxRestored.exe"

 

Option Explicit

' EFS Backup
' Windows 2000 or later
' egl1044
Public Const ERROR_SUCCESS As Long = 0
Public Const INVALID_HANDLE_VALUE As Long = (-1)
Public Const GENERIC_READ As Long = &H80000000
Public Const GENERIC_WRITE As Long = &H40000000
Public Const OPEN_EXISTING As Long = &H3&
Public Const CREATE_ALWAYS As Long = &H2&

Public Enum EncryptionStatus
  FILE_ENCRYPTABLE = 0            'The file can be encrypted.
  FILE_IS_ENCRYPTED = 1           'The file is encrypted.
  FILE_READ_ONLY = 8              'The file is a read-only file.
  FILE_ROOT_DIR = 3               'The file is a root directory. Root directories cannot be encrypted.
  FILE_SYSTEM_ATTR = 2            'The file is a system file. System files cannot be encrypted.
  FILE_SYSTEM_DIR = 4             'The file is a system directory. System directories cannot be encrypted.
  FILE_SYSTEM_NOT_SUPPORT = 6     'The file system does not support file encryption.
  FILE_UNKNOWN = 5                'The encryption status is unknown. The file may be encrypted.
  FILE_USER_DISALLOWED = 7        'Reserved for future use.
End Enum

Public Enum EncryptedFileFlags
  CREATE_FOR_EXPORT = 0           'Open the file for export (backup).
  CREATE_FOR_IMPORT = 1           'The file is being opened for import (restore).
  CREATE_FOR_DIR = 2              'Import (restore) a directory containing encrypted files. This must be combined with one of the previous two flags to indicate the operation.
  OVERWRITE_HIDDEN = 4            'Overwrite a hidden file on import.
End Enum

Public Declare Function CreateFileW Lib "Kernel32.dll" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

Public Declare Function ReadFile Lib "Kernel32.dll" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long

Public Declare Function WriteFile Lib "Kernel32.dll" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal nNumberOfBytesToWrite As Long, ByRef lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long

Public Declare Function CloseHandle Lib "Kernel32.dll" (ByVal hObject As Long) As Long

Public Declare Function FileEncryptionStatusW Lib "Advapi32.dll" (ByVal lpFileName As Long, ByRef lpStatus As Long) As Long
  
Public Declare Function OpenEncryptedFileRawW Lib "Advapi32.dll" (ByVal lpFileName As Long, ByVal ulFlags As EncryptedFileFlags, ByRef pvContext As Long) As Long

Public Declare Function ReadEncryptedFileRaw Lib "Advapi32.dll" (ByVal pfExportCallback As Long, ByVal pvCallbackContext As Long, ByVal pvContext As Long) As Long
  
Public Declare Function WriteEncryptedFileRaw Lib "Advapi32.dll" (ByVal pfImportCallback As Long, ByVal pvCallbackContext As Long, ByVal pvContext As Long) As Long

Public Declare Function CloseEncryptedFileRaw Lib "Advapi32.dll" (ByVal pvContext As Long) As Long

    
Public Sub Backup(ByVal sourceFile As String, ByVal targetFile As String)
  
  Dim hFileSource     As Long
  Dim ctx             As Long
  
  ' Create new file that will store the raw encrypted backup data.
  hFileSource = CreateFileW(StrPtr("\\?\" & targetFile), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0)
  If hFileSource = INVALID_HANDLE_VALUE Then
    Debug.Print "CreateFile failed."; Err.LastDllError
    Exit Sub
  End If
  ' Open the source file and write the raw encrypted data into the backup file.
  If OpenEncryptedFileRawW(StrPtr(sourceFile), CREATE_FOR_EXPORT, ctx) = ERROR_SUCCESS Then
    ReadEncryptedFileRaw AddressOf ExportCallback, hFileSource, ctx
    CloseEncryptedFileRaw ctx
  Else
    Debug.Print "OpenEncryptedFileRaw failed."; Err.LastDllError
  End If
  ' cleanUp
  CloseHandle hFileSource
  
End Sub

Public Sub Restore(ByVal sourceFile As String, ByVal targetFile As String)

  Dim hFileSource     As Long
  Dim hFileTarget     As Long
  Dim ctx             As Long
  
  ' Create new file that will restore the raw encrypted backup data.
  hFileTarget = CreateFileW(StrPtr("\\?\" & targetFile), 0, 0, 0, CREATE_ALWAYS, 0, 0)
  If hFileTarget = INVALID_HANDLE_VALUE Then
    Debug.Print "CreateFile failed."; Err.LastDllError
    Exit Sub
  End If
  ' cleanUp
  CloseHandle hFileTarget
  
  ' Open the raw encrypted backup file.
  hFileSource = CreateFileW(StrPtr("\\?\" & sourceFile), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0)
  If hFileSource = INVALID_HANDLE_VALUE Then
    Debug.Print "CreateFile failed."; Err.LastDllError
    Exit Sub
  End If
  
  ' Open the raw backup file and restore the raw backup data.
  If OpenEncryptedFileRawW(StrPtr(targetFile), CREATE_FOR_IMPORT, ctx) = ERROR_SUCCESS Then
    WriteEncryptedFileRaw AddressOf ImportCallback, hFileSource, ctx
    CloseEncryptedFileRaw ctx
  Else
    Debug.Print "OpenEncryptedFileRaw failed."; Err.LastDllError
  End If
  ' cleanUp
  CloseHandle hFileSource

End Sub

Public Function ImportCallback( _
  ByVal pbData As Long, _
  ByVal pvCallbackContext As Long, _
  ByRef ulLength As Long) As Long
  ' Restore Callback
  Dim dwReadBytes As Long
  ReadFile pvCallbackContext, pbData, ulLength, dwReadBytes, 0
  ulLength = dwReadBytes
  ImportCallback = ERROR_SUCCESS
End Function

Public Function ExportCallback( _
  ByVal pbData As Long, _
  ByVal pvCallbackContext As Long, _
  ByVal ulLength As Long) As Long
  'Backup Callback
  Dim dwWrittenBytes As Long
  WriteFile pvCallbackContext, pbData, ulLength, dwWrittenBytes, 0
End Function

Open in new window

0
 

Author Closing Comment

by:Cefer
ID: 33503713
Thank you for the example code.  I am very grateful.
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 33505428
Your welcome buddy, Everything working as expected?
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question