#include "main.h" #include "./deviceSupportedCommandStore.h" DeviceSupportedCommandStore::DeviceSupportedCommandStore() : ref(1) { InitializeCriticalSection(&lock); } DeviceSupportedCommandStore::~DeviceSupportedCommandStore() { RemoveAll(); DeleteCriticalSection(&lock); } HRESULT DeviceSupportedCommandStore::CreateInstance(DeviceSupportedCommandStore **instance) { if (NULL == instance) return E_POINTER; *instance = new DeviceSupportedCommandStore(); if (NULL == *instance) return E_OUTOFMEMORY; return S_OK; } size_t DeviceSupportedCommandStore::AddRef() { return InterlockedIncrement((LONG*)&ref); } size_t DeviceSupportedCommandStore::Release() { if (0 == ref) return ref; LONG r = InterlockedDecrement((LONG*)&ref); if (0 == r) delete(this); return r; } int DeviceSupportedCommandStore::QueryInterface(GUID interface_guid, void **object) { if (NULL == object) return E_POINTER; if (IsEqualIID(interface_guid, IFC_DeviceSupportedCommandStore)) *object = static_cast(this); else { *object = NULL; return E_NOINTERFACE; } if (NULL == *object) return E_UNEXPECTED; AddRef(); return S_OK; } void DeviceSupportedCommandStore::Lock() { EnterCriticalSection(&lock); } void DeviceSupportedCommandStore::Unlock() { LeaveCriticalSection(&lock); } int DeviceSupportedCommandStore::SortCallback(const void *element1, const void *element2) { DeviceSupportedCommand *command1, *command2; command1 = *(DeviceSupportedCommand**)element1; command2 = *(DeviceSupportedCommand**)element2; return CompareStringA(CSTR_INVARIANT, 0, command1->GetName(), -1, command2->GetName(), -1) - 2; } int DeviceSupportedCommandStore::SearchCallback(const void *key, const void *element) { const char *name; DeviceSupportedCommand *command; name = (const char*)key; command = *(DeviceSupportedCommand**)element; return CompareStringA(CSTR_INVARIANT, 0, name, -1, command->GetName(), -1) - 2; } DeviceSupportedCommand *DeviceSupportedCommandStore::Find(const char *name, size_t *indexOut) { DeviceSupportedCommand *command; int length; size_t index, count; if (NULL == name || '\0' == *name) return NULL; length = lstrlenA(name); count = commandList.size(); for(index = 0; index < count; index++) { command = commandList[index]; if (CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, 0, name, length, command->GetName(), -1)) break; } if (count == index) return NULL; if (NULL != indexOut) *indexOut = index; return command; } HRESULT DeviceSupportedCommandStore::Add(const char *name, DeviceCommandFlags flags) { HRESULT hr; DeviceSupportedCommand *command; hr = DeviceSupportedCommand::CreateInstance(name, &command); if (FAILED(hr)) return hr; Lock(); if (NULL == Find(name, NULL)) { command->SetFlags(flags, flags); commandList.push_back(command); } else { command->Release(); hr = S_FALSE; } Unlock(); return hr; } HRESULT DeviceSupportedCommandStore::Remove(const char *name) { HRESULT hr; size_t index; DeviceSupportedCommand *command; Lock(); command = Find(name, &index); if (NULL != command) { commandList.erase(commandList.begin() + index); command->Release(); hr = S_OK; } else { hr = S_FALSE; } Unlock(); return hr; } HRESULT DeviceSupportedCommandStore::RemoveAll() { Lock(); size_t index = commandList.size(); while(index--) { DeviceSupportedCommand *command = commandList[index]; command->Release(); } commandList.clear(); Unlock(); return S_OK; } HRESULT DeviceSupportedCommandStore::GetFlags(const char *name, DeviceCommandFlags *flagsOut) { HRESULT hr; DeviceSupportedCommand *command; if (NULL == flagsOut) return E_POINTER; Lock(); command = Find(name, NULL); hr = (NULL != command) ? command->GetFlags(flagsOut) : E_FAIL; Unlock(); return hr; } HRESULT DeviceSupportedCommandStore::SetFlags(const char *name, DeviceCommandFlags mask, DeviceCommandFlags value) { HRESULT hr; DeviceSupportedCommand *command; Lock(); command = Find(name, NULL); hr = (NULL != command) ? command->SetFlags(mask, value) : E_FAIL; Unlock(); return hr; } HRESULT DeviceSupportedCommandStore::Get(const char *name, ifc_devicesupportedcommand **command) { HRESULT hr; if (NULL == command) return E_POINTER; Lock(); *command = Find(name, NULL); if (NULL != *command) { (*command)->AddRef(); hr = S_OK; } else hr = E_FAIL; Unlock(); return hr; } HRESULT DeviceSupportedCommandStore::GetActive(ifc_devicesupportedcommand **command) { return E_NOTIMPL; } HRESULT DeviceSupportedCommandStore::Enumerate(ifc_devicesupportedcommandenum **enumerator) { HRESULT hr; Lock(); hr = DeviceSupportedCommandEnum::CreateInstance( reinterpret_cast(commandList.size() ? &commandList.at(0) : nullptr), commandList.size(), reinterpret_cast(enumerator)); Unlock(); return hr; } HRESULT DeviceSupportedCommandStore::Clone(ifc_devicesupportedcommandstore **instance, BOOL fullCopy) { HRESULT hr; DeviceSupportedCommandStore *clone; DeviceSupportedCommand *command; if (NULL == instance) return E_POINTER; Lock(); hr = CreateInstance(&clone); if (SUCCEEDED(hr)) { size_t index, count; count = commandList.size(); for(index = 0; index < count; index++) { command = commandList[index]; if (FALSE != fullCopy) { DeviceSupportedCommand *commandClone; hr = command->Clone(&commandClone); if(SUCCEEDED(hr)) command = commandClone; else break; } else command->AddRef(); clone->commandList.push_back(command); } } Unlock(); if (FAILED(hr) && NULL != clone) { clone->Release(); *instance = NULL; } else *instance = clone; return hr; } #define CBCLASS DeviceSupportedCommandStore START_DISPATCH; CB(ADDREF, AddRef) CB(RELEASE, Release) CB(QUERYINTERFACE, QueryInterface) CB(API_ADD, Add) CB(API_REMOVE, Remove) CB(API_REMOVEALL, RemoveAll) CB(API_GETFLAGS, GetFlags) CB(API_SETFLAGS, SetFlags) CB(API_GET, Get) CB(API_GETACTIVE, GetActive) CB(API_ENUMERATE, Enumerate) CB(API_CLONE, Clone) END_DISPATCH; #undef CBCLASS