Solved

.NET File.Copy createing new zero length files when using local accounts with Windows Service

Posted on 2009-05-06
3
258 Views
Last Modified: 2013-11-08
Greetings,

I have an interesting problem with a Win32 service I wrote in VB.NET that uses a FileSystemWatcher object in a Windows Service to catch new files in a directory and move them to a file share on a different domain server. The service is using the File.Copy method to copy the files and rename them. The server with the service / File.Copy code is not part of a domain and uses a local admin account (pospay) to run the service. The domain server with the destination file share has a matching pospay user account with a synchronized password. The service starts fine and successfully works ONCE to copy the new file to the share but after the initial success in copying the file intact all subsequent File.Copy operations result in new, zero length files until I restart the server. This includes changing the service to not use the domain file share location and instead use it's own desktop folder. The files are still new, zero length files with the same name as the originating file.
Imports System.IO
Imports System.Xml
Imports System.ComponentModel
Imports System.ServiceProcess
 
 
Public Class PositivePayWatcher
 
  Inherits System.ServiceProcess.ServiceBase
 
  Const ApDestination As String = "\\tundra2\Workgrps\FNSB\Wf Positive Pay\jct_test\ap"
  Const PyDestination As String = "\\tundra2\Workgrps\FNSB\Wf Positive Pay\jct_test\py"
  Const ApWatchLocation As String = "c:\\fnsb\pospay\ap"
  Const PyWatchLocation As String = "c:\\fnsb\pospay\py"
  Const TransferLogLocation As String = "\\tundra2\Workgrps\FNSB\Wf Positive Pay\jct_test\pospay.xml"
  Private TransferType As String
  Private LoggingXmlDoc As New XmlDocument
 
 
  Protected Overrides Sub OnStart(ByVal args() As String)
 
    'AP -------------------------------------------------------------------									
    fswAP.Path = ApWatchLocation
    fswAP.NotifyFilter = IO.NotifyFilters.FileName  'watch operation/task
 
    'PY -------------------------------------------------------------------
    fswPY.Path = PyWatchLocation
    fswPY.NotifyFilter = IO.NotifyFilters.FileName  'watch operation/task
 
    'Log ------------------------------------------------------------------
    If File.Exists(TransferLogLocation) Then LoggingXmlDoc.Load(TransferLogLocation)
 
  End Sub
 
 
 
  Private Sub WatchForChanges_Payroll(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles fswPY.Created
 
    Dim filename As String = e.Name
 
    Try
      TransferType = "PY"
      File.Copy(e.FullPath, PyDestination & "\" & filename, True) 'use built in file transfer utility to move the file and rename it csv
      LogTranfer(filename, PyDestination & "\" & filename, TransferType)
    Catch ex As Exception
      Dim logdata As New IO.StreamWriter("c:\fnsb\wf.txt", True, Text.Encoding.ASCII)
      logdata.Write(ex.Message.ToString & vbCrLf)
      logdata.Close()
    End Try
 
  End Sub

Open in new window

0
Comment
Question by:akjtr
[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
  • 2
3 Comments
 
LVL 15

Assisted Solution

by:oobayly
oobayly earned 100 total points
ID: 24324364
Can we assume that no errors are being logged?
0
 

Author Comment

by:akjtr
ID: 24328812
No errors are being logged through the stream writer object nor app event log on the server. There are no security errors on the domain file share either.
0
 

Accepted Solution

by:
akjtr earned 0 total points
ID: 24498269
I used the following class as a workaround. I fired ImpersonateStart prior to calling the file.move or file.copy. Also I just thought about one reason why the original code may not have worked and that is our McAfee virus engines are paranoid. It may have been unrelated to security and more to do with VE. Anyway the class:

Imports System
Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
Imports Microsoft.VisualBasic
<Assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True), _
 Assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name:="FullTrust")> 
 
Public Class RunAs_Impersonator
#Region "Private Variables and Enum Constants"
  Private tokenHandle As New IntPtr(0)
  Private dupeTokenHandle As New IntPtr(0)
  Private impersonatedUser As WindowsImpersonationContext
#End Region
#Region "Properties"
 
#End Region
#Region "Public Methods"
  Public Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean
 
  Public Declare Auto Function DuplicateToken Lib "advapi32.dll" (ByVal ExistingTokenHandle As IntPtr, _
    ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _
    ByRef DuplicateTokenHandle As IntPtr) As Boolean
 
  ' Test harness.
  ' If you incorporate this code into a DLL, be sure to demand FullTrust.
  <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
  Public Sub ImpersonateStart(ByVal Domain As String, ByVal userName As String, ByVal Password As String)
    Try
      tokenHandle = IntPtr.Zero
      ' Call LogonUser to obtain a handle to an access token.
      Dim returnValue As Boolean = LogonUser(userName, Domain, Password, 2, 0, tokenHandle)
 
      'check if logon successful
      If returnValue = False Then
        Dim ret As Integer = Marshal.GetLastWin32Error()
        Console.WriteLine("LogonUser failed with error code : {0}", ret)
        Throw New System.ComponentModel.Win32Exception(ret)
        Exit Sub
      End If
 
      'Logon succeeded
 
      ' Use the token handle returned by LogonUser.
      Dim newId As New WindowsIdentity(tokenHandle)
      impersonatedUser = newId.Impersonate()
    Catch ex As Exception
      Throw ex
      Exit Sub
    End Try
    ' MsgBox("running as " & impersonatedUser.ToString & " -- " & WindowsIdentity.GetCurrent.Name)
  End Sub
  <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
  Public Sub ImpersonateStop()
    ' Stop impersonating the user.
    impersonatedUser.Undo()
 
    ' Free the tokens.
    If Not System.IntPtr.op_Equality(tokenHandle, IntPtr.Zero) Then
      CloseHandle(tokenHandle)
    End If
    'MsgBox("running as " & Environment.UserName)
  End Sub
#End Region
#Region "Private Methods"
  Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
   ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
   ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
   ByRef phToken As IntPtr) As Boolean
 
  <DllImport("kernel32.dll")> _
  Public Shared Function FormatMessage(ByVal dwFlags As Integer, ByRef lpSource As IntPtr, _
   ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByRef lpBuffer As [String], _
   ByVal nSize As Integer, ByRef Arguments As IntPtr) As Integer
  End Function
#End Region
 
End Class

Open in new window

0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

740 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