Community technical support mailing list was retired 2010 and replaced with a professional technical support team. For assistance please contact: Pre-sales Technical support via email to sales@march-hare.com.
Hello, we run a CVSNT-Client on Windows-2000 and XP (2.0.58d) using a Standard-CVS Server on Linux. Whenever a file is produced from the CVSNT-Client (checkout/update/export) this file has so called Extended-Attributes which are only defined in NTFS. These EAs are not set prior checkin by us. These EAs are not visible using Explorer and we dont know the meaning of it. The effect is that such files can not be copied into our samba fileserver. It creates an empty file on the target dir but stops with an error about "source may be in use" - which is wrong of course. They can be copied when the destination is using NTFS or FAT. When the files are zipped/unzipped the EAs are deleted and the file then can be copied everywhere. The question is - is that a bug or a feature of CVSNT? Can anybody reproduce the behaviour? Is the EA using configurable (switch off)? Which information is stored into the EA? Do we have maybe misconfigured our samba (running unchanged since years)? Best regards, Andreas Winter PS: Below is the output of a tool showing the attributes (source below) for a fresh file produced from cvsnt. stream [0] "": type: security size: 176 stream [0] "": type: data size: 469 stream [0] "": type: extended attributes size: 22 After zipping/unzipping the part with type: extended attributes is missing. Below is a source we found - which can display the EA in a file. We found that source during a google session - it is not from us. --------------------------------------- // ntfsstream.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <stdio.h> #include <stdlib.h> typedef unsigned char byte; #pragma hdrstop #define err doerr( __FILE__, __LINE__ ) void doerr( const char *file, int line ) { DWORD e; e = GetLastError(); if ( e == 0 ) return; printf( "%s(%d): gle = %lu\n", file, line, e ); exit( 2 ); } void enableprivs() { HANDLE hToken; byte buf[sizeof TOKEN_PRIVILEGES * 2]; TOKEN_PRIVILEGES & tkp = *( (TOKEN_PRIVILEGES *) buf ); if ( ! OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) err; // enable SeBackupPrivilege, SeRestorePrivilege if ( !LookupPrivilegeValue( NULL, SE_BACKUP_NAME, &tkp.Privileges[0].Luid ) ) err; if ( !LookupPrivilegeValue( NULL, SE_RESTORE_NAME, &tkp.Privileges[1].Luid ) ) err; tkp.PrivilegeCount = 2; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tkp.Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ); } void dumphdr( WIN32_STREAM_ID & wsi ) { const char *p; printf( "\nstream [%lu] \"%S\":\n", wsi.dwStreamNameSize, wsi.dwStreamNameSize? wsi.cStreamName: L"" ); switch ( wsi.dwStreamId ) { case BACKUP_DATA: p = "data"; break; case BACKUP_EA_DATA: p = "extended attributes"; break; case BACKUP_SECURITY_DATA: p = "security"; break; case BACKUP_ALTERNATE_DATA: p = "other streams"; break; case BACKUP_LINK: p = "link"; break; default: p = "unknown"; break; } printf( " type: %s\n", p ); printf( " size: %I64d\n", wsi.Size.QuadPart ); } int main( int argc, char *argv[] ) { HANDLE fh; if ( argc != 2 ) { printf( "usage: dump_ntfs_streams {file}\n" ); return 1; } // SeBackupPrivilege is not necessary to enumerate streams -- // but it helps if you are an admin/backup-operator and need // to scan files to which you have no permissions enableprivs(); fh = CreateFile( argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS, NULL ); if ( fh == INVALID_HANDLE_VALUE || fh == NULL ) err; byte buf[4096]; DWORD numread, numtoskip; void *ctx = NULL; WIN32_STREAM_ID & wsi = *( (WIN32_STREAM_ID *) buf ); numtoskip = 0; while ( 1 ) { // we are at the start of a stream header. read it. if ( ! BackupRead( fh, buf, 20, &numread, FALSE, TRUE, &ctx ) ) err; if ( numread == 0 ) break; if ( wsi.dwStreamNameSize > 0 ) { if ( ! BackupRead( fh, buf + 20, wsi.dwStreamNameSize, &numread, FALSE, TRUE, &ctx ) ) err; if ( numread != wsi.dwStreamNameSize ) break; } dumphdr( wsi ); // skip stream data if ( wsi.Size.QuadPart > 0 ) { DWORD lo, hi; BackupSeek( fh, 0xffffffffL, 0x7fffffffL, &lo, &hi, &ctx ); } } // make NT release the context BackupRead( fh, buf, 0, &numread, TRUE, FALSE, &ctx ); CloseHandle( fh ); return 0; } --------------------------- Best regards, Andreas Winter