123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- #include "main.h"
- #include "./deviceIconStore.h"
- #include <strsafe.h>
- DeviceIconStore::DeviceIconStore()
- : ref(1), base(NULL)
- {
- InitializeCriticalSection(&lock);
- }
- DeviceIconStore::~DeviceIconStore()
- {
- RemoveAll();
- String_Free(base);
- DeleteCriticalSection(&lock);
- }
- HRESULT DeviceIconStore::CreateInstance(DeviceIconStore **instance)
- {
- if (NULL == instance)
- return E_POINTER;
- *instance = new DeviceIconStore();
- if (NULL == *instance)
- return E_OUTOFMEMORY;
- return S_OK;
- }
- size_t DeviceIconStore::AddRef()
- {
- return InterlockedIncrement((LONG*)&ref);
- }
- size_t DeviceIconStore::Release()
- {
- if (0 == ref)
- return ref;
-
- LONG r = InterlockedDecrement((LONG*)&ref);
- if (0 == r)
- delete(this);
-
- return r;
- }
- int DeviceIconStore::QueryInterface(GUID interface_guid, void **object)
- {
- if (NULL == object) return E_POINTER;
-
- if (IsEqualIID(interface_guid, IFC_DeviceIconStore))
- *object = static_cast<ifc_deviceiconstore*>(this);
- else
- {
- *object = NULL;
- return E_NOINTERFACE;
- }
- if (NULL == *object)
- return E_UNEXPECTED;
- AddRef();
- return S_OK;
- }
- void DeviceIconStore::Lock()
- {
- EnterCriticalSection(&lock);
- }
- void DeviceIconStore::Unlock()
- {
- LeaveCriticalSection(&lock);
- }
- HRESULT DeviceIconStore::Add(const wchar_t *path, unsigned int width, unsigned int height, BOOL replaceExisting)
- {
- if (FALSE != IS_STRING_EMPTY(path))
- return E_INVALIDARG;
- if(width < 1)
- width = 1;
- if(height < 1)
- height = 1;
- HRESULT hr = S_FALSE;
- Lock();
- size_t index = list.size();
- while(index--)
- {
- Record *record = &list[index];
- if (width == record->width &&
- height == record->height)
- {
- if (FALSE == replaceExisting)
- hr = E_FAIL;
- else
- {
- wchar_t *pathCopy;
- pathCopy = String_Duplicate(path);
- if (NULL == pathCopy)
- hr = E_OUTOFMEMORY;
- else
- {
- record->path = pathCopy;
- hr = S_OK;
- }
- }
- break;
- }
- }
-
- if (S_FALSE == hr)
- {
- Record newRecord;
- newRecord.path = String_Duplicate(path);
- if (NULL == newRecord.path)
- hr = E_OUTOFMEMORY;
- else
- {
- newRecord.width = width;
- newRecord.height = height;
- list.push_back(newRecord);
- hr = S_OK;
- }
- }
-
- Unlock();
- return hr;
- }
- HRESULT DeviceIconStore::Remove(unsigned int width, unsigned int height)
- {
- HRESULT hr;
- size_t index;
- Record *record;
- if(width < 1)
- width = 1;
- if(height < 1)
- height = 1;
- hr = S_FALSE;
- Lock();
- index = list.size();
- while(index--)
- {
- record = &list[index];
- if (record->width == width &&
- record->height == height)
- {
- String_Free(record->path);
- list.erase(list.begin() + index);
- hr = S_OK;
- break;
- }
- }
- Unlock();
- return hr;
- }
- HRESULT DeviceIconStore::RemovePath(const wchar_t *path)
- {
- HRESULT hr;
- size_t index;
- Record *record;
- if (FALSE != IS_STRING_EMPTY(path))
- return E_INVALIDARG;
- hr = S_FALSE;
- Lock();
- index = list.size();
- while(index--)
- {
- record = &list[index];
- if(CSTR_EQUAL == CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, record->path, -1, path, -1))
- {
- String_Free(record->path);
- list.erase(list.begin() + index);
- hr = S_OK;
- }
- }
- Unlock();
- return hr;
- }
- HRESULT DeviceIconStore::RemoveAll()
- {
- size_t index;
- Record *record;
- Lock();
- index = list.size();
- while(index--)
- {
- record = &list[index];
- String_Free(record->path);
- }
- list.clear();
-
- Unlock();
-
- return S_OK;
- }
- HRESULT DeviceIconStore::Get(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height)
- {
- HRESULT hr;
- Record *record;
- const wchar_t *path;
- size_t index;
- double widthDbl, heightDbl;
- double scaleMin, scaleHorz, scaleVert;
- if (NULL == buffer)
- return E_POINTER;
- if (width < 1)
- width = 1;
- if (height < 1)
- height = 1;
- path = NULL;
-
- widthDbl = width;
- heightDbl = height;
- Lock();
- index = list.size();
- if (index > 0)
- {
- record = &list[--index];
- scaleHorz = widthDbl/record->width;
- scaleVert = heightDbl/record->height;
- scaleMin = (scaleHorz < scaleVert) ? scaleHorz : scaleVert;
- path = record->path;
- if (1.0 != scaleMin)
- {
- scaleMin = fabs(1.0 - scaleMin);
- while(index--)
- {
- record = &list[index];
- scaleHorz = widthDbl/record->width;
- scaleVert = heightDbl/record->height;
- if (scaleHorz > scaleVert)
- scaleHorz = scaleVert;
-
- if (1.0 == scaleHorz)
- {
- path = record->path;
- break;
- }
-
- scaleHorz = fabs(1.0 - scaleHorz);
- if (scaleHorz < scaleMin)
- {
- scaleMin = scaleHorz;
- path = record->path;
- }
- }
- }
- }
-
- if (NULL == path)
- hr = E_FAIL;
- else
- hr = GetFullPath(buffer, bufferMax, path);
-
- Unlock();
- return hr;
- }
- HRESULT DeviceIconStore::GetExact(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height)
- {
- HRESULT hr;
- size_t index;
- Record *record;
- if (NULL == buffer)
- return E_POINTER;
- if(width < 1)
- width = 1;
- if(height < 1)
- height = 1;
- hr = E_FAIL;
- Lock();
- index = list.size();
- while(index--)
- {
- record = &list[index];
- if (record->width == width &&
- record->height == height)
- {
- hr = GetFullPath(buffer, bufferMax, record->path);
- break;
- }
- }
- Unlock();
- return hr;
- }
- HRESULT DeviceIconStore::SetBasePath(const wchar_t *path)
- {
- HRESULT hr;
- Lock();
-
- String_Free(base);
- base = String_Duplicate(path);
-
- if (NULL == base && NULL != path)
- hr = E_OUTOFMEMORY;
- else
- hr = S_OK;
-
- Unlock();
- return hr;
- }
- HRESULT DeviceIconStore::GetBasePath(wchar_t *buffer, size_t bufferMax)
- {
- HRESULT hr;
-
- if (NULL == buffer)
- return E_POINTER;
- Lock();
- if (0 == String_CopyTo(buffer, base, bufferMax) &&
- FALSE == IS_STRING_EMPTY(base))
- {
- hr = E_FAIL;
- }
- else
- hr = S_OK;
- Unlock();
- return hr;
- }
- HRESULT DeviceIconStore::Clone(ifc_deviceiconstore **instance)
- {
- HRESULT hr;
- DeviceIconStore *clone;
-
- if (NULL == instance)
- return E_POINTER;
- hr = DeviceIconStore::CreateInstance(&clone);
- if (FAILED(hr))
- return hr;
- Lock();
-
- clone->base = String_Duplicate(base);
- if (NULL == clone->base && NULL != base)
- hr = E_OUTOFMEMORY;
- else
- {
- size_t index, count;
- Record target;
- const Record *source;
- count = list.size();
- for(index = 0; index < count; index++)
- {
- source = &list[index];
- target.path = String_Duplicate(source->path);
- if (NULL == target.path)
- {
- hr = E_OUTOFMEMORY;
- break;
- }
- else
- {
- target.width = source->width;
- target.height = source->height;
- clone->list.push_back(target);
- }
- }
- }
-
- Unlock();
- if (FAILED(hr))
- clone->Release();
- else
- *instance = clone;
- return hr;
- }
- HRESULT DeviceIconStore::Enumerate(EnumeratorCallback callback, void *user)
- {
- size_t index, count;
- wchar_t buffer[MAX_PATH*2] = {0};
- Record *record;
- if (NULL == callback)
- return E_POINTER;
- Lock();
- count = list.size();
- for(index = 0; index < count; index++)
- {
- record = &list[index];
- if (SUCCEEDED(GetFullPath(buffer, ARRAYSIZE(buffer), record->path)))
- {
- if (FALSE == callback(buffer, record->width, record->height, user))
- {
- break;
- }
- }
- }
- Unlock();
- return S_OK;
- }
- HRESULT DeviceIconStore::GetFullPath(wchar_t *buffer, size_t bufferMax, const wchar_t *path)
- {
- HRESULT hr;
- if (NULL == buffer)
- return E_POINTER;
- if (FALSE != IS_STRING_EMPTY(path))
- return E_INVALIDARG;
- Lock();
- if (FALSE == PathIsRelative(path) ||
- FALSE != IS_STRING_EMPTY(base))
- {
- if (0 == String_CopyTo(buffer, path, bufferMax))
- hr = E_OUTOFMEMORY;
- else
- hr = S_OK;
- }
- else
- {
- if (NULL == PathCombine(buffer, base, path))
- hr = E_FAIL;
- else
- hr = S_OK;
- }
-
- Unlock();
- return hr;
- }
- #define CBCLASS DeviceIconStore
- START_DISPATCH;
- CB(ADDREF, AddRef)
- CB(RELEASE, Release)
- CB(QUERYINTERFACE, QueryInterface)
- CB(API_ADD, Add)
- CB(API_REMOVE, Remove)
- CB(API_REMOVEPATH, RemovePath)
- CB(API_REMOVEALL, RemoveAll)
- CB(API_GET, Get)
- CB(API_GETEXACT, GetExact)
- CB(API_SETBASEPATH, SetBasePath)
- CB(API_GETBASEPATH, GetBasePath)
- CB(API_CLONE, Clone)
- CB(API_ENUMERATE, Enumerate)
- END_DISPATCH;
- #undef CBCLASS
|