Solved

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

Posted on 2009-05-06
3
240 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
  • 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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
DataGridView 2 29
asp.net mvc5 3 38
Unable  to create new object 9 28
Different Delete Messages 7 23
A basic question.. “What is the Garbage Collector?” The usual answer given back: “Garbage collector is a background thread run by the CLR for freeing up the memory space used by the objects which are no longer used by the program.” I wondered …
In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

747 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now