VSS - Procedure stack corruption [resolved]

Windows specific forum
PureGuy
Enthusiast
Enthusiast
Posts: 102
Joined: Mon Aug 30, 2010 11:51 am

VSS - Procedure stack corruption [resolved]

Post by PureGuy »

Hi, I'm using the following code to create a volume shadow copy and it worked great on my Windows 7 x64.
Now I wanted to use it on a 32-bit windows 7 machine , but Purifier breaks with "Procedure stack corruption"

It always happens on the AddToSnapshotSet() call.

I'm really have no idea what's going wrong. It's definitive not the windows installation other program can use vss successful.

Code: Select all

EnableExplicit

DataSection
  GUID_NULL:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $00, $00, $00, $00, $00, $00, $00, $00
EndDataSection

Interface IVssBackupComponents Extends IUnknown
  GetWriterComponentsCount(pcComponents)
  GetWriterComponents(iWriter.l, ppWriter)
  InitializeForBackup(bstrXML)
  SetBackupState(bSelectComponents.l, bBackupBootableSystemState.l, backupType, bPartialFileSupport.l)
  InitializeForRestore(bstrXML)
  SetRestoreState(restoreType)  
  GatherWriterMetadata(pAsync)
  GetWriterMetadataCount(pcWriters)
  GetWriterMetadata(iWriter.l, pidInstance, ppMetadata)
  FreeWriterMetadata()
  AddComponent(instanceId, writerId, ct, wszLogicalPath, wszComponentName)
  PrepareForBackup(pAsync)
  AbortBackup()
  GatherWriterStatus(pAsync)
  GetWriterStatusCount(pcWriters)
  FreeWriterStatus()
  GetWriterStatus(iWriter.l, pidInstance, pidWriter, pbstrWriter, pnStatus, phResultFailure)
  SetBackupSucceeded(instanceId, writerId, ct, wszLogicalPath, wszComponentName, bSucceded.l)
  SetBackupOptions(writerId, ct, wszLogicalPath, wszComponentName, bSucceded.l)
  SetSelectedForRestore(writerId, ct, wszLogicalPath, wszComponentName, bSelectedForRestore.l)
  SetRestoreOptions(writerId, ct, wszLogicalPath, wszComponentName, wszRestoreOptions)
  SetAdditionalRestores(writerId, ct, wszLogicalPath, wszComponentName, wszPreviousBackupStamp)
  SetPreviousBackupStamp(writerId, componentType, wszLogicalPath, wszComponentName, wszPreviousBackupStamp)
  SaveAsXML(pbstrXML)
  BackupComplete(ppAsync)
  AddAlternativeLocationMapping(writerId, componentType, wszLogicalPath, wszComponentName, wszPath, wszFilespec, bRecursive.l, wszDestination)
  AddRestoreSubcomponent(writerId, componentType, wszLogicalPath, wszComponentName, wszSubComponentLogicalPath, wszSubComponentName, bRepair.l)
  SetFileRestoreStatus(writerId, ct, wszLogicalPath, wszComponentName, status.l)
  AddNewTarget(writerId, ct, wszLogicalPath, wszComponentName, wszPath, wszFileName, bRecursive.l, wszAlternatePath)
  SetRangesFilePath(writerId, ct, wszLogicalPath, wszComponentName, iPartialFile, wszRangesFile)
  PreRestore(ppAsync)
  PostRestore(ppAsync)
  SetContext(lContext.l)
  StartSnapshotSet(pSnapshotSetId)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    AddToSnapshotSet(pwszVolumeName, ProviderId, pidSnapshot)
  CompilerElse
    AddToSnapshotSet(pwszVolumeName, ProviderId1.q, ProviderId2.q, pidSnapshot)
  CompilerEndIf  
  DoSnapshotSet(ppAsync)
  DeleteSnapshots(SourceObjectId, eSourceObjectType, bForceDelete.l, plDeletedSnapshots, pNondeletedSnapshotID)
  ImportSnapshots(ppAsync)
  BreakSnapshotSet(SnapshotSetId)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    GetSnapshotProperties(SnapshotId, pProp)
  CompilerElse
    GetSnapshotProperties(SnapshotId1.q, SnapshotId2.q, pProp)
  CompilerEndIf 
  Query(QueriedObjectId, eQueriedObjectType, eReturnedObjectsType, ppEnum)
  IsVolumeSupported(ProviderId, pwszVolumeName, pbSupportedByThisProvider)
  DisableWriterClasses(rgWriterClassId, cClassId.l)
  EnableWriterClasses(rgWriterClassId, cClassId.l)
  DisableWriterInstances(rgWriterInstanceId, cInstanceId.l)
  ExposeSnapshot(SnapshotId, wszPathFromRoot, lAttributes.l, wszExpose, pwszExposed)
  RevertToSnapshot(SnapshotId, bForceDismount.l)
  QueryRevertStatus(pwszVolume, ppAsync)
EndInterface

Interface IVssAsync Extends IUnknown
  Cancel()
  Wait(dwMilliseconds.l = $FFFFFFFF)
  QueryStatus(pHrResult, pReserved)
EndInterface

#VSS_CTX_BACKUP   = 0
#VSS_CTX_FILE_SHARE_BACKUP   = $10
#VSS_CTX_NAS_ROLLBACK   = $19
#VSS_CTX_APP_ROLLBACK   = $09
#VSS_CTX_CLIENT_ACCESSIBLE   = $1D
#VSS_CTX_CLIENT_ACCESSIBLE_WRITERS  = $0D
#VSS_CTX_ALL   = $ffffffff

Enumeration VSS_BACKUP_TYPE
  #VSS_BT_UNDEFINED
  #VSS_BT_FULL
  #VSS_BT_INCREMENTAL
  #VSS_BT_DIFFERENTIAL
  #VSS_BT_LOG
  #VSS_BT_COPY
  #VSS_BT_OTHER
EndEnumeration

#RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6
#RPC_C_IMP_LEVEL_IDENTIFY = 2
#EOAC_NONE = 0

Structure _VSS_SNAPSHOT_PROP Align #PB_Structure_AlignC
  m_SnapshotId.guid
  m_SnapshotSetId.guid
  m_lSnapshotsCount.l
  m_pwszSnapshotDeviceObject.i
  m_pwszOriginalVolumeName.i
  m_pwszOriginatingMachine.i
  m_pwszServiceMachine.i
  m_pwszExposedName.i
  m_pwszExposedPath.i
  m_ProviderId.guid
  m_lSnapshotAttributes.l
  m_tsCreationTimestamp.q
  m_eStatus.i
EndStructure

Prototype pCreateVssBackupComponents(ppBackup)
Prototype pVssFreeSnapshotProperties(Prop)

Procedure.s ShadowVolume(sVolume.s)
    
  Protected pPtr.Integer, oVSS.IVssBackupComponents, snapshotPropstructure._VSS_SNAPSHOT_PROP
  Protected hr, vss_lib, snapshotProp, guid_snapshot.guid, sReturn.s
  Protected oVssAsync.IVssAsync
  
  vss_lib = OpenLibrary(#PB_Any, "vssapi.dll")
  If Not vss_lib : ProcedureReturn :  CloseLibrary(vss_lib) : EndIf
  
  Protected CreateVssBackupComponents_.pCreateVssBackupComponents = GetFunction(vss_lib, "CreateVssBackupComponentsInternal")
  Protected VssFreeSnapshotProperties_.pVssFreeSnapshotProperties = GetFunction(vss_lib, "VssFreeSnapshotProperties")
  If Not CreateVssBackupComponents_ Or Not VssFreeSnapshotProperties_ : CloseLibrary(vss_lib) : ProcedureReturn : EndIf
  
  CoInitializeEx_(0, #COINIT_MULTITHREADED)
  
  CoInitializeSecurity_(0, 1, 0, 0, #RPC_C_AUTHN_LEVEL_PKT_PRIVACY, #RPC_C_IMP_LEVEL_IDENTIFY, 0, #EOAC_NONE, 0)
     
  hr = CreateVssBackupComponents_(@pPtr)
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
  
  oVSS = pPtr\i
  hr = oVss\InitializeForBackup(0)
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
  
  hr = oVss\SetContext(#VSS_CTX_BACKUP | #VSS_CTX_CLIENT_ACCESSIBLE_WRITERS | #VSS_CTX_APP_ROLLBACK)
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf               
  
  hr = oVss\GatherWriterMetadata(@pPtr)
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
    
  oVssAsync = pPtr\i
  hr = oVssAsync\Wait()
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
  
  oVssAsync\Release()
  hr = oVss\StartSnapshotSet(guid_snapshot)
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
  
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    hr = oVss\AddToSnapshotSet(@sVolume, ?GUID_NULL, guid_snapshot)
  CompilerElse
    Protected quad1.q, quad2.q
    hr = oVss\AddToSnapshotSet(@sVolume, quad1.q, quad2.q, guid_snapshot)
  CompilerEndIf 
  
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
  
  hr = oVss\SetBackupState(0, 0, #VSS_BT_FULL, 0)
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
  
  hr = oVss\PrepareForBackup(@pPtr)
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf                  
                    
  oVssAsync = pPtr\i
  hr = oVssAsync\Wait()
  oVssAsync\Release()
              
  hr = oVss\DoSnapshotSet(@pPtr)
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
  oVssAsync = pPtr\i
  oVssAsync\Release()
  
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    hr = oVss\GetSnapshotProperties(guid_snapshot, snapshotPropstructure)
  CompilerElse
    quad1.q = PeekQ(guid_snapshot)
    quad2.q = PeekQ(guid_snapshot + 8)
    hr = oVss\GetSnapshotProperties(quad1.q, quad2.q, snapshotPropstructure)
  CompilerEndIf
  
  If Not hr = #ERROR_SUCCESS : Goto _error : EndIf
  If snapshotPropstructure\m_pwszSnapshotDeviceObject
    sReturn = PeekS(snapshotPropstructure\m_pwszSnapshotDeviceObject)
  EndIf
                            
  VssFreeSnapshotProperties_(snapshotPropstructure)                             
  
  _error:
  
  If oVSS : oVSS\Release() : EndIf
  
  CoUninitialize_()
  
  CloseLibrary(vss_lib)
    
  ProcedureReturn sReturn
  
EndProcedure

Debug ShadowVolume("C:\")
BTW: To test it you have to set Unicode and "request admin rights"
After Error occurs, you should stop the VSS service (open admin cmd and type net stop vss)
Last edited by PureGuy on Thu Jul 24, 2014 10:16 am, edited 2 times in total.
Sundance
User
User
Posts: 16
Joined: Sat Jun 07, 2014 10:12 am

Re: VSS - Procedure stack corruption

Post by Sundance »

Hu PureGuy,

some weeks ago I wrote a script in AutoIt which does also shadow copys and one of the guys there did a change to let the script also run under 64Bit. The change was in the definition of AddToSnapshotSet.

http://www.autoitscript.com/forum/topic ... try1161178
http://www.autoitscript.com/forum/topic ... try1160368

Hope this helps. When I have time, I will also take a look at it.


see you soon
Sundance
PureGuy
Enthusiast
Enthusiast
Posts: 102
Joined: Mon Aug 30, 2010 11:51 am

Re: VSS - Procedure stack corruption

Post by PureGuy »

Thanks you Sundance!
HRESULT AddToSnapshotSet(
[in] VSS_PWSZ pwszVolumeName,
[in] VSS_ID ProviderId,
[out] VSS_ID *pidSnapshot
);

"AddToSnapshotSet hresult(wstr; uint64; uint64; ptr);"
That's works for AddToSnapshotSet() but it's even more confusing.
Mabye you can ask this Lars about GetSnapshotProperties(), ift seems to have the same problem.

Using two quad's the counter part for Autoit3's unit64 nor using 4 longs for the guid doesn't work.
Sundance
User
User
Posts: 16
Joined: Sat Jun 07, 2014 10:12 am

Re: VSS - Procedure stack corruption

Post by Sundance »

Hi PureGuy,

can you post your working code? I will take a look and also try to ask on the AutoIt forum!

see you
Sundance

Edit: In AutoIt I see no difference in GetSnapshotProperties. On both (x86/X64) they are defined the same way.
PureGuy
Enthusiast
Enthusiast
Posts: 102
Joined: Mon Aug 30, 2010 11:51 am

Re: VSS - Procedure stack corruption

Post by PureGuy »

I have updated the code, it should work now for both interpreters.

Keep in mind this creates permanent shadows, if you don't delete them in your code, you have to do it manually with:

vssadmin delete shadows /For=C:
Sundance
User
User
Posts: 16
Joined: Sat Jun 07, 2014 10:12 am

Re: VSS - Procedure stack corruption

Post by Sundance »

Hi.

Thanks for the update. After creation within a test script i would call DeleteSnapshots to delete them...
I will test it tomorrow.

see you sundance
Sundance
User
User
Posts: 16
Joined: Sat Jun 07, 2014 10:12 am

Re: VSS - Procedure stack corruption

Post by Sundance »

Hi PureGuy,

this code works for Windows Vista and greater.
When trying to use the code under Windows XP or Windows Server2003 the CreateVssBackupComponentsInternal call won't be found.
What I found on the internet is to download the microsoft vss sdk7.2 and use the given libs/includes for windows xp and 2003. But i think we can make it work without those files. But when i use the ExamineLibraryFunction i can't see a usable exportet function...

Has someone a hint for me?


thanks in advance
Sundance
PureGuy
Enthusiast
Enthusiast
Posts: 102
Joined: Mon Aug 30, 2010 11:51 am

Re: VSS - Procedure stack corruption

Post by PureGuy »

XP has a different Interface, you will need to convert it from the older SDK.
For the CreateVssBackupComponentsInternal call try this:

Code: Select all

CreateVssBackupComponents_.pCreateVssBackupComponents = GetFunction(vss_lib, "?CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z")
Sundance
User
User
Posts: 16
Joined: Sat Jun 07, 2014 10:12 am

Re: VSS - Procedure stack corruption [resolved]

Post by Sundance »

Hi PureGuy,

I saw that entry but must have made an copy/paste mistake the first time. Seems it throws no error. Will try to get further the way.

Thanks !!

see you
Sundance
Post Reply