Volume backup using VSS in vc++ - visual-c++

Can anyone suggest me how to do volume backup?
below is my code. Creating shapshot of C: drive and tryinh to backed up and using CopyFile to backup file by file. Is their any way to backup valume?
cout<<"=============Begin Initialize=========="<<endl;
if(FAILED(CoInitializeEx(NULL,0)))
{
cout << "CoInitialize() failed\n";
return(0);
}
if(FAILED(CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IDENTIFY,
NULL,
EOAC_NONE,
NULL)))
{
cout << "CoInitializeSecurity() failed\n";
return(0);
}
if(FAILED(CreateVssBackupComponents(&m_pVssObject)))
{
cout << "CreateVssBackupComponents() failed\n";
return(0);
}
if(FAILED(m_pVssObject->InitializeForBackup()))
{
cout << "IVssBackupComponents->InitializeForBackup() failed\n";
return(0);
}
// if(FAILED(m_pVssObject->SetContext(dwContext)))
if(FAILED(m_pVssObject->SetContext(VSS_CTX_BACKUP | VSS_CTX_APP_ROLLBACK)))
{
cout << "IVssBackupComponents->SetContext() failed\n";
return(0);
}
if(FAILED(m_pVssObject->SetBackupState(true,true,VSS_BT_FULL,false)))
{
cout << "IVssBackupComponents->SetContext() failed\n";
return(0);
}
cout<<"=============End Initialize=========="<<endl;
// Start the shadow set
CHECK_COM(m_pVssObject->StartSnapshotSet(&m_latestSnapshotSetID))
GetVolumePathNameW((LPCWSTR)wstrVolume.c_str(),wszVolumePathName, MAX_PATH);
CHECK_COM(m_pVssObject->IsVolumeSupported(GUID_NULL, wszVolumePathName, &supported));
// Add the specified volumes to the shadow set
VSS_ID SnapshotID;
CHECK_COM(m_pVssObject->AddToSnapshotSet(wszVolumePathName, GUID_NULL, &SnapShotId));
m_latestSnapshotIdList.push_back(SnapshotID);
cout<<"Prepare the shadow for backup\n";
CHECK_COM(m_pVssObject->PrepareForBackup(&pPrepare));
cout<<"Waiting for the asynchronous operation to finish..."<<endl;
CHECK_COM(pPrepare->Wait());
HRESULT hrReturned = S_OK;
CHECK_COM(pPrepare->QueryStatus(&hrReturned, NULL));
// Check if the async operation succeeded...
if(FAILED(hrReturned))
{
cout<<"Error during the last asynchronous operation."<<endl;
}
pPrepare->Release();
cout<<"Creating the shadow (DoSnapshotSet) ... "<<endl;
CHECK_COM(m_pVssObject->DoSnapshotSet(&pDoShadowCopy));
cout<<"Waiting for the asynchronous operation to finish..."<<endl;
CHECK_COM(pDoShadowCopy->Wait());
hrReturned = S_OK;
CHECK_COM(pDoShadowCopy->QueryStatus(&hrReturned, NULL));
// Check if the async operation succeeded...
if(FAILED(hrReturned))
{
cout<<"Error during the last asynchronous operation."<<endl;
}
pDoShadowCopy->Release();
HRESULT result;
//CHECK_COM(m_pVssObject->GetSnapshotProperties(SnapShotId,&props));
result=m_pVssObject->GetSnapshotProperties(SnapShotId,&props);
if(result== S_OK)
{
_tprintf (_T(" Snapshot Id :") WSTR_GUID_FMT _T("\n"), GUID_PRINTF_ARG( props.m_SnapshotId));
_tprintf (_T(" Snapshot Set ID :") WSTR_GUID_FMT _T("\n"), GUID_PRINTF_ARG( props.m_SnapshotSetId));
_tprintf (_T(" Provider ID :") WSTR_GUID_FMT _T("\n"), GUID_PRINTF_ARG( props.m_ProviderId));
_tprintf (_T(" OriginalVolumeName : %ls\n"),props.m_pwszOriginalVolumeName);
if(props.m_pwszExposedPath != NULL) _tprintf (_T(" Exposed Path : %ls\n"),props.m_pwszExposedPath);
if(props.m_pwszExposedName != NULL) _tprintf (_T(" Exposed Path Name : %ls\n"),props.m_pwszExposedName);
if(props.m_pwszSnapshotDeviceObject != NULL) _tprintf (_T(" SnapShot device object: %ls\n"),props.m_pwszSnapshotDeviceObject);
SYSTEMTIME stUTC, stLocal;
FILETIME ftCreate;
ftCreate.dwHighDateTime = HILONG(props.m_tsCreationTimestamp);
ftCreate.dwLowDateTime = LOLONG(props.m_tsCreationTimestamp);
FileTimeToSystemTime(&ftCreate, &stUTC);
SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
_tprintf (TEXT("Created : %02d/%02d/%d %02d:%02d \n"), stLocal.wMonth, stLocal.wDay, stLocal.wYear, stLocal.wHour, stLocal.wMinute );
_tprintf (_T("\n"));
}
WCHAR sam_file[1024];
wsprintf(sam_file,L"%s%s",props.m_pwszSnapshotDeviceObject,L"\\WINDOWS\\System32\\Config\\SAM");
CopyFile(sam_file,L"c:\\temp\\dbg_sm_bkup",FALSE);
VssFreeSnapshotProperties(&props);
m_pVssObject->Release();
Thanks in Advance

You can do volume shadow copy using vshadow tool. Source code also available online also with sdks. Go through the following link,
http://msdn.microsoft.com/en-us/library/windows/desktop/bb530725(v=vs.85).aspx

Related

How can I validate a subset of a RapidJSON document?

I'm using RapidJSON to parse messages that (roughly) conform to JSON-RPC. Here's an example of one such message:
{
"method": "increment",
"params": [ { "count": 42 } ]
}
The content of params depends on the value of method, so... I need to validate against a different schema for each possible value of method. As a step towards this goal, I created a map of schema documents, keyed by the method name:
std::unordered_map<std::string, rapidjson::SchemaDocument> schemas;
My intention was to do something like this (after parsing the received JSON into a RapidJSON document, doc):
if (schemas.find(doc["method"]) != schemas.end()) {
validate(doc, schemas[doc]);
}
My problem is: I know how to validate a rapidjson::Document, but not a GenericValue instance (which is, I gather, what doc["method"] returns).
How can I validate a fragment or 'sub-document' of a RapidJSON document?
UPDATE/EXPLANATION: Thanks to #wsxedcrfv's answer, I now realize that my statement saying "I know how to validate a rapidjson::Document wasn't entirely accurate. I knew one way of validating a rapidjson::Document. But there's more than one way to do it, apparently. To clean up this question a bit for posterity, here's the validate() function that was missing from my original question:
bool validate(
rj::SchemaDocument const& schema,
rj::Document *doc,
std::string const& jsonMsg
)
{
bool valid = false;
rj::StringStream ss(jsonMsg.c_str());
rj::SchemaValidatingReader<
rj::kParseDefaultFlags,
rj::StringStream,
rj::UTF8<>
> reader(ss, schema);
doc->Populate(reader);
if (!reader.GetParseResult()) {
if (!reader.IsValid()) {
rj::StringBuffer sb;
reader.GetInvalidSchemaPointer().StringifyUriFragment(sb);
printf("Message does not conform to schema!\n");
printf("--------------------------------------------------------------------\n");
printf("Invalid schema: %s\n", sb.GetString());
printf("Invalid keyword: %s\n", reader.GetInvalidSchemaKeyword());
sb.Clear();
reader.GetInvalidDocumentPointer().StringifyUriFragment(sb);
printf("Invalid document: %s\n", sb.GetString());
printf("--------------------------------------------------------------------\n");
}
else {
printf("Message JSON is not well-formed!\n");
}
}
else {
valid = true;
}
return valid;
}
As #wsxedcrfv points out, another option is to create a SchemaValidator instance and pass it to the Accept() method of the (sub-)document:
#include "rapidjson/document.h"
#include <rapidjson/schema.h>
#include <iostream>
namespace rj = rapidjson;
namespace
{
std::string testMsg = R"msg({ "root": { "method": "control", "params": [ { "icc_delta_vol": 5 } ] } })msg";
std::string msgSchema = R"schema(
{
"type": "object",
"properties": {
"method": { "$ref": "#/definitions/method" },
"params": { "$ref": "#/definitions/paramsList" }
},
"required": [ "method", "params" ],
"additionalProperties": false,
"definitions": {
// Omitted in the interest of brevity
...
}
})schema";
} // End anonymous namespace
int main()
{
rj::Document schemaDoc;
if (schemaDoc.Parse(::msgSchema.c_str()).HasParseError()) {
std::cout << "Schema contains invalid JSON, aborting...\n";
exit(EXIT_FAILURE);
}
rj::SchemaDocument schema(schemaDoc);
rj::SchemaValidator validator(schema);
rj::Document doc;
doc.Parse(::testMsg.c_str());
std::cout << "doc.Accept(validator) = " << doc["root"].Accept(validator) << '\n';
return 0;
Now that I know about this alternate method, I can easily use it to do context-specific validation of sub-documents/fragments...
I guess this answer is a bit late for you, but this works for me:
char json[] = "{ \"a\" : 1, \"b\" : 1.2 } ";
rapidjson::Document d;
std::cout << "parse json error? " << d.Parse(json).HasParseError() << "\n";
char schema[] = "{ \"type\" : \"integer\" } ";
rapidjson::Document sd;
std::cout << "parse schema error? " << sd.Parse(schema).HasParseError() << "\n";
rapidjson::SchemaDocument s{sd}; //sd may now be deleted
rapidjson::SchemaValidator vali{s};
std::cout << "json " << d.Accept(vali) << "\n"; // 0
vali.Reset();
std::cout << "a " << d.GetObject()["a"].Accept(vali) << "\n"; // 1
vali.Reset();
std::cout << "b " << d.GetObject()["b"].Accept(vali) << "\n"; // 0
I don't know which validate function you are using, but a Document is a GenericValue and the GenericValue provides Accept.

How to get installed application path for executable in COM

I am trying to get the installed location of all application using COM. I am able to get the display name of each application. But I am not able to get installed path of each application.
MY Code:
CComPtr<IShellItem> spPrinters;
CoInitialize(nullptr);
HRESULT hresult = ::SHCreateItemFromParsingName(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\"
L"::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr, IID_PPV_ARGS(&spPrinters));
CComPtr<IEnumShellItems> spEnum;
spPrinters->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&spEnum));
for (CComPtr<IShellItem> spProgram; spEnum->Next(1, &spProgram, nullptr) == S_OK; spProgram.Release())
{
CComHeapPtr<wchar_t> spszName;
spProgram->GetDisplayName(SIGDN_NORMALDISPLAY, &spszName);
CString cDisplayName = spszName;
}
Any idea how to get installed path from IEnumShellItems?
Here is a piece of code that will dump this out. The child's IPropertyStore does not return these, I don't know why, so we have to use the old
IShellFolder2::GetDetailsEx method with a special column id (which is the same as a PROPERTYKEY).
CComPtr<IShellItem> cpl;
CComPtr<IShellFolder2> folder;
CComPtr<IEnumShellItems> enumerator;
PROPERTYKEY pkLocation;
SHCreateItemFromParsingName(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr, IID_PPV_ARGS(&cpl));
// bind to IShellFolder
cpl->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&folder));
// bind to IEnumShellItems
cpl->BindToHandler(NULL, BHID_EnumItems, IID_PPV_ARGS(&enumerator));
// get this property key's value
PSGetPropertyKeyFromName(L"System.Software.InstallLocation", &pkLocation);
for (CComPtr<IShellItem> child; enumerator->Next(1, &child, nullptr) == S_OK; child.Release())
{
// get child's display name
CComHeapPtr<wchar_t> name;
child->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
wprintf(L"%s\n", name);
// get child's PIDL
CComHeapPtr<ITEMIDLIST> pidl;
SHGetIDListFromObject(child, &pidl);
// the PIDL is absolute, we need the relative one (the last itemId in the list)
// get it's install location
CComVariant v;
if (SUCCEEDED(folder->GetDetailsEx(ILFindLastID(pidl), &pkLocation, &v)))
{
// it's a VT_BSTR
wprintf(L" %s\n", v.bstrVal);
}
}
Note it's using an undocumented System.Software.InstallLocation PROPERTYKEY. To find it I just dumped all columns with a code like this for each child:
int iCol = 0;
do
{
SHCOLUMNID colId;
if (FAILED(folder->MapColumnToSCID(iCol, &colId)))
break; // last column
CComHeapPtr<wchar_t> name;
PSGetNameFromPropertyKey(colId, &name);
CComVariant v;
if (SUCCEEDED(folder->GetDetailsEx(ILFindLastID(pidl), &colId, &v)))
{
if (v.vt == VT_BSTR)
{
wprintf(L" %s: %s\n", name, v.bstrVal);
}
else
{
wprintf(L" %s vt: %i\n", name, v.vt);
}
}
iCol++;
} while (true);
}
PS: I've not added much error checking, but you should.

C++/CLI code doesn't enter .then part of the create_task function

This is the code that I have:
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
XTRACE(L"=========================================will start onNavigated ");
auto mediaCapture = ref new Windows::Media::Capture::MediaCapture();
m_mediaCaptureMgr = mediaCapture;
IAsyncAction ^asyncAction = m_mediaCaptureMgr->InitializeAsync();
try
{
create_task(asyncAction).then([this](task<void> initTask)
{
XTRACE(L"=========================================will start onNavigated 2");
try
{
initTask.get();
auto mediaCapture = m_mediaCaptureMgr.Get();
if (mediaCapture->MediaCaptureSettings->VideoDeviceId != nullptr && mediaCapture->MediaCaptureSettings->AudioDeviceId != nullptr)
{
String ^fileName;
fileName = VIDEO_FILE_NAME;
XTRACE(L"=================================Device initialized successful\n");
create_task(KnownFolders::VideosLibrary->CreateFileAsync(fileName, Windows::Storage::CreationCollisionOption::GenerateUniqueName))
.then([this](task<StorageFile^> fileTask)
{
XTRACE(L"=================================Create record file successful\n");
m_recordStorageFile = fileTask.get();
MediaEncodingProfile^ recordProfile = nullptr;
recordProfile = MediaEncodingProfile::CreateMp4(Windows::Media::MediaProperties::VideoEncodingQuality::Auto);
stream = ref new InMemoryRandomAccessStream();
return m_mediaCaptureMgr->StartRecordToStreamAsync(recordProfile, stream);
}).then([this](task<void> recordTask)
{
try
{
recordTask.get();
XTRACE(L"=================================Start Record successful\n");
}
catch (Exception ^e)
{
XTRACE(L"======ERRROR is : %d", e);
}
});
}
else
{
XTRACE(L"=================================No VideoDevice/AudioDevice Found\n");
}
XTRACE(L"=================================WILL EXIT \n");
}
catch (Exception ^ e)
{
XTRACE(L"============================================ERROR IS: %d\n", e);
}
}
);
}
catch (Exception ^ e)
{
XTRACE(L"============================================before create task ERROR IS: %d\n", e);
}
XTRACE(L"=================================SLEEP 20000====================================\n");
std::chrono::milliseconds dura(20000);
std::this_thread::sleep_for(dura);
XTRACE(L"=================================TIME ENDED====================================\n");
// stop device detection
try
{
XTRACE(L"=================================Stopping Record\n");
create_task(m_mediaCaptureMgr->StopRecordAsync())
.then([this](task<void> recordTask)
{
try
{
recordTask.get();
XTRACE(L"=================================Stop record successful: %d\n", stream->Size);
}
catch (Exception ^e)
{
XTRACE(L"=================================ERROR while stoping 2: %d\n", e);
}
});
}
catch (Exception ^e)
{
XTRACE(L"=================================ERROR try catch 3 stoping: %d\n", e);
}
CloseHandle(ghEvent);
// destruct the device manager
XTRACE(L"=====================================================================END\n");
}
In the log I see:
=========================================will start onNavigated
And then directly:
=====================================================================
=================================SLEEP 20000====================================
What is strange is that I had this code in a unittest and it worked, I created a new windows phone project with a UI and it doesn't work
Apparently it was because of the ThreadSleep:
std::chrono::milliseconds dura(20000);
std::this_thread::sleep_for(dura);
In the library project where I was working I was using a different sleep, provided by the library, and that would work. So this was the line that would cause the application to block itself.
I worked my way around this by including 2 buttons in the app, for the start and stop recording.

Use iXMLHttpRequest2 to download zip file

I am trying to port cocos2dx application for Windows phone 8. I am trying to use iXMLHTTPRequest class to perform Network calls in C++.
I am trying to download zip file using this but dont know what and where I am doing wrong. Here is my code which I am using, Please help me to figure out the issue and what I should do to make it working.
void HTTPRequest::sendRequest(){
m_cancelHttpRequestSource = cancellation_token_source();
// Set up the GET request parameters.
std::string s_str = std::string(urlString);
std::wstring wid_str = std::wstring(s_str.begin(), s_str.end());
const wchar_t* w_char = wid_str.c_str();
auto uri = ref new Uri( ref new String(w_char));
String ^temp = uri->AbsoluteUri;
auto token = m_cancelHttpRequestSource.get_token();
// Send the request and then update the UI.
onHttpRequestCompleted(m_httpRequest.GetAsync(uri, token));
}
void HTTPRequest::onHttpRequestCompleted(concurrency::task httpRequest)
{
httpRequest.then([this](task previousTask)
{
try
{
wstring response = previousTask.get();
if (m_httpRequest.GetStatusCode() == 200)
{
size_t strSize;
FILE* fileHandle;
auto local = Windows::Storage::ApplicationData::Current->LocalFolder;
auto localFileNamePlatformString = local->Path + "\\test1.zip";
// Create an the xml file in text and Unicode encoding mode.
if ((fileHandle = _wfopen(localFileNamePlatformString->Data(), L"wb")) == NULL) // C4996
// Note: _wfopen is deprecated; consider using _wfopen_s instead
{
wprintf(L"_wfopen failed!\n");
return(0);
}
// Write a string into the file.
strSize = wcslen(response.c_str());
if (fwrite(response.c_str(), sizeof(wchar_t), strSize, fileHandle) != strSize)
{
wprintf(L"fwrite failed!\n");
}
// Close the file.
if (fclose(fileHandle))
{
wprintf(L"fclose failed!\n");
}
}
else
{
// The request failed. Show the status code and reason.
wstringstream ss;
ss << L"The server returned "
<< m_httpRequest.GetStatusCode()
<< L" ("
<< m_httpRequest.GetReasonPhrase()
<< L')';
//String ^responseText = ref new String(ss.str().c_str());
m_delegate->parserError(requestType->getCString(), "Print Status Code later");
}
}
catch (const task_canceled&)
{
// Indicate that the operation was canceled.
//String ^responseText = "The operation was canceled";
m_delegate->parserError(requestType->getCString(), "Operation has canceled");
}
catch (Exception^ e)
{
// Indicate that the operation failed.
//String ^responseText = "The operation failed";
m_delegate->parserError(requestType->getCString(), "The operation failed");
// TODO: Handle the error further.
(void)e;
}
}, task_continuation_context::use_current());
}

Natively buffering audio

This probably is one of my own mistakes, but I can't seem to find what is wrong. After trying to improve performance of my application, I moved audio buffering from the Java layer to the native layer. Audio handling (recording/playing) is already done natively using the OpenSL ES API.
Yet the native buffering is causing my application to crash whenever I start the application. I use a simple Queue implementation as my buffer, where the first node is the oldest data (FIFO).
struct bufferNode{
struct bufferNode* next;
jbyte* data;
};
struct bufferQueue{
struct bufferNode* first;
struct bufferNode* last;
int size;
};
The audio data is referred to by the jbyte* in the bufferNode. Access to the Queue is done via these two methods, and is synchronized with a mutex.
void enqueueInBuffer(struct bufferQueue* queue, jbyte* data){
SLresult result;
if(queue != NULL){
if(data != NULL){
result = pthread_mutex_lock(&recMutex);
if(result != 0){
decodeMutexResult(result);
logErr("EnqueueInBuffer", "Unable to acquire recording mutex");
} else {
struct bufferNode* node = (struct bufferNode*)malloc(sizeof(struct bufferNode));
if(node == NULL){
logErr("EnqueueInBuffer", "Insufficient memory available to buffer new audio");
} else {
node->data = data;
if(queue->first == NULL){
queue->first = queue->last = node;
} else {
queue->last->next = node;
queue->last = node;
}
queue->size = queue->size + 1;
node->next = NULL;
}
}
result = pthread_mutex_unlock(&recMutex);
if(result != 0){
decodeMutexResult(result);
logErr("EnqueueInBuffer", "Unable to release recording mutex");
}
} else {
logErr("EnqueueInBuffer", "Data is NULL");
}
} else {
logErr("EnqueueInBuffer", "Queue is NULL");
}
}
void dequeueFromBuffer(struct bufferQueue* queue, jbyte* returnData){
SLresult result;
result = pthread_mutex_lock(&recMutex);
if(result != 0){
decodeMutexResult(result);
logErr("DequeueFromBuffer", "Unable to acquire recording mutex");
} else {
if(queue->first == NULL){
returnData = NULL;
} else {
returnData = queue->first->data;
struct bufferNode* tmp = queue->first;
if(queue->first == queue->last){
queue->first = queue->last = NULL;
} else {
queue->first = queue->first->next;
}
free(tmp);
queue->size = queue->size - 1;
}
}
result = pthread_mutex_unlock(&recMutex);
if(result != 0){
decodeMutexResult(result);
logErr("DequeueFromBuffer", "Unable to release recording mutex");
}
}
Where the log and decode methods are selfdeclared utility methods. Log just logs the message to the logcat, while the decode methods "decode" any error number possible from the previous method call.
Yet I keep getting an error when I try to enqueue audio data. Whenever I call the enqueueInBuffer method, I get a SIGSEGV native error, with code 1 (SEGV_MAPERR). Yet I can't seem to find what is causing the error. Both the Queue and the audio data exist when I try to make the enqueueInBuffer method call (which is done in an OpenSL ES Recorder callback, hence the synchronization).
Is there something else going on what causes the segmentation fault? Probably I am responsible for it, but I can't seem to find the error.
Apparently, this was caused by a line of code I have in my OpenSL ES Recorder callback.
The callback originally looked like this:
void recorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context){
SLresult result;
enqueueInBuffer(&recordingQueue, (*recorderBuffers[queueIndex]));
result = (*bq)->Enqueue(bq, recorderBuffers[queueIndex], RECORDER_FRAMES * sizeof(jbyte));
if(checkError(result, "RecorderCallB", "Unable to enqueue new buffer on recorder") == -1){
return;
}
queueIndex = queueIndex++ % MAX_RECORDER_BUFFERS;
}
However, it seems that the last line of the callback didn't correctly create the new index. The buffers I use are in an array, which is 4 long.
Changing the last line to
queueIndex = (queueIndex + 1) % MAX_RECORDER_BUFFERS;
seems to have fixed the error.

Resources