Update of /cvsroot/pywin32/pywin32/win32/Demos
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30904/win32/Demos
Added Files:
BackupRead_BackupWrite.py BackupSeek_streamheaders.py
Log Message:
Demos showing how to use BackupRead, BackupWrite, and BackupSeek to duplicate files and enumerate streams
--- NEW FILE: BackupRead_BackupWrite.py ---
## demonstrates using BackupRead and BackupWrite to copy all of a file's data streams
import win32file, win32api, win32con, win32security, ntsecuritycon
from win32com import storagecon
import pythoncom, pywintypes
import struct, traceback
all_sd_info=win32security.DACL_SECURITY_INFORMATION|win32security.DACL_SECURITY_INFORMATION| \
win32security.OWNER_SECURITY_INFORMATION|win32security.GROUP_SECURITY_INFORMATION
tempdir=win32api.GetTempPath()
tempfile=win32api.GetTempFileName(tempdir,'bkr')[0]
outfile=win32api.GetTempFileName(tempdir,'out')[0]
print 'Filename:',tempfile,'Output file:',outfile
f=open(tempfile,'w')
f.write('some random junk'+'x'*100)
f.close()
## add a couple of alternate data streams
f=open(tempfile+':streamdata','w')
f.write('data written to alternate stream'+'y'*100)
f.close()
f=open(tempfile+':anotherstream','w')
f.write('z'*100)
f.close()
## add Summary Information, which is stored as a separate stream
m=storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE |storagecon.STGM_DIRECT
pss=pythoncom.StgOpenStorageEx(tempfile, m, storagecon.STGFMT_FILE, 0 , pythoncom.IID_IPropertySetStorage,None)
ps=pss.Create(pythoncom.FMTID_SummaryInformation,pythoncom.IID_IPropertyStorage,0,storagecon.STGM_READWRITE|storagecon.STGM_SHARE_EXCLUSIVE)
ps.WriteMultiple((storagecon.PIDSI_KEYWORDS,storagecon.PIDSI_COMMENTS),('keywords','comments'))
ps=None
pss=None
## add a custom security descriptor to make sure we don't
## get a default that would always be the same for both files in temp dir
new_sd=pywintypes.SECURITY_DESCRIPTOR()
sid=win32security.LookupAccountName('','EveryOne')[0]
acl=pywintypes.ACL()
acl.AddAccessAllowedAce(1, win32con.GENERIC_READ, sid)
acl.AddAccessAllowedAce(1, ntsecuritycon.FILE_APPEND_DATA, sid)
acl.AddAccessAllowedAce(1, win32con.GENERIC_WRITE, sid)
acl.AddAccessAllowedAce(1, ntsecuritycon.FILE_ALL_ACCESS, sid)
new_sd.SetSecurityDescriptorDacl(True, acl, False)
win32security.SetFileSecurity(tempfile,win32security.DACL_SECURITY_INFORMATION,new_sd)
sa=pywintypes.SECURITY_ATTRIBUTES()
sa.bInheritHandle=True
h=win32file.CreateFile(tempfile, win32con.GENERIC_ALL ,win32con.FILE_SHARE_READ,
sa, win32con.OPEN_EXISTING, win32file.FILE_FLAG_BACKUP_SEMANTICS , None)
outh=win32file.CreateFile(outfile, win32con.GENERIC_ALL ,win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,
sa, win32con.OPEN_EXISTING, win32file.FILE_FLAG_BACKUP_SEMANTICS , None)
ctxt=0
outctxt=0
buf=None
readsize=100
while 1:
bytes_read, buf, ctxt=win32file.BackupRead(h, readsize, buf, False, True, ctxt)
if bytes_read==0:
break
bytes_written, outctxt=win32file.BackupWrite(outh, bytes_read, buf, False, True, outctxt)
print 'Written:',bytes_written,'Context:',outctxt
win32file.BackupRead(h, 0, buf, True, True, ctxt)
win32file.BackupWrite(outh, 0, '', True, True, outctxt)
win32file.CloseHandle(h)
win32file.CloseHandle(outh)
assert open(tempfile).read()==open(outfile).read(),"File contents differ !"
assert open(tempfile+':streamdata').read()==open(outfile+':streamdata').read(),"streamdata contents differ !"
assert open(tempfile+':anotherstream').read()==open(outfile+':anotherstream').read(),"anotherstream contents differ !"
assert buffer(win32security.GetFileSecurity(tempfile,all_sd_info))[:]== \
buffer(win32security.GetFileSecurity(outfile, all_sd_info))[:], "Security descriptors are different !"
## also should check Summary Info programatically
--- NEW FILE: BackupSeek_streamheaders.py ---
## demonstrates using BackupSeek to enumerate data streams for a file
import win32file, win32api, win32con
from win32com import storagecon
import pythoncom, pywintypes
import struct, traceback
stream_types={
win32con.BACKUP_DATA:"Standard data",
win32con.BACKUP_EA_DATA:"Extended attribute data",
win32con.BACKUP_SECURITY_DATA:"Security descriptor data",
win32con.BACKUP_ALTERNATE_DATA:"Alternative data streams",
win32con.BACKUP_LINK:"Hard link information",
win32con.BACKUP_PROPERTY_DATA:"Property data",
win32con.BACKUP_OBJECT_ID:"Objects identifiers",
win32con.BACKUP_REPARSE_DATA:"Reparse points",
win32con.BACKUP_SPARSE_BLOCK:"Sparse file"
}
tempdir=win32api.GetTempPath()
tempfile=win32api.GetTempFileName(tempdir,'bkr')[0]
print 'Filename:',tempfile
f=open(tempfile,'w')
f.write('some random junk'+'x'*100)
f.close()
f=open(tempfile+':streamdata','w')
f.write('data written to alternate stream'+'y'*100)
f.close()
f=open(tempfile+':anotherstream','w')
f.write('z'*200)
f.close()
## add Summary Information, which is stored as a separate stream
m=storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE |storagecon.STGM_DIRECT
pss=pythoncom.StgOpenStorageEx(tempfile, m, storagecon.STGFMT_FILE, 0 , pythoncom.IID_IPropertySetStorage,None)
ps=pss.Create(pythoncom.FMTID_SummaryInformation,pythoncom.IID_IPropertyStorage,0,storagecon.STGM_READWRITE|storagecon.STGM_SHARE_EXCLUSIVE)
ps.WriteMultiple((storagecon.PIDSI_KEYWORDS,storagecon.PIDSI_COMMENTS),('keywords','comments'))
ps=None
pss=None
sa=pywintypes.SECURITY_ATTRIBUTES()
sa.bInheritHandle=False
h=win32file.CreateFile(tempfile, win32con.GENERIC_ALL ,win32con.FILE_SHARE_READ,
sa, win32con.OPEN_EXISTING, win32file.FILE_FLAG_BACKUP_SEMANTICS , None)
""" stream header:
typedef struct _WIN32_STREAM_ID {
DWORD dwStreamId; DWORD dwStreamAttributes; LARGE_INTEGER Size;
DWORD dwStreamNameSize; WCHAR cStreamName[ANYSIZE_ARRAY];
}
"""
win32_stream_id_format="LLQL"
win32_stream_id_size=struct.calcsize(win32_stream_id_format)
def parse_stream_header(h,ctxt,data):
stream_type, stream_attributes, stream_size, stream_name_size=struct.unpack(win32_stream_id_format,data)
print '\nType:',stream_type,stream_types[stream_type], 'Attributes:', stream_attributes, 'Size:', stream_size, 'Name len:',stream_name_size
if stream_name_size>0:
## ??? sdk says this size is in characters, but it appears to be number of bytes ???
bytes_read, stream_name_buf, ctxt=win32file.BackupRead(h, stream_name_size, None, False, True, ctxt)
stream_name=pywintypes.UnicodeFromRaw(stream_name_buf[:])
else:
stream_name='Unnamed'
print 'Name:'+stream_name
return ctxt, stream_type, stream_attributes, stream_size, stream_name_size, stream_name
ctxt=0
win32_stream_id_buf=None ## gets rebound to a writable buffer on first call and reused
while 1:
bytes_read, win32_stream_id_buf, ctxt=win32file.BackupRead(h, win32_stream_id_size, win32_stream_id_buf, False, True, ctxt)
if bytes_read==0:
break
ctxt, stream_type, stream_attributes, stream_size, stream_name_size, stream_name=\
parse_stream_header(h, ctxt, win32_stream_id_buf[:])
if stream_size>0:
bytes_moved=win32file.BackupSeek(h, stream_size, ctxt)
print 'Moved: ',bytes_moved
win32file.BackupRead(h, win32_stream_id_size, win32_stream_id_buf, True, True, ctxt)
win32file.CloseHandle(h)
|