diff --git a/dlls/itss/chm_lib.c b/dlls/itss/chm_lib.c index a98c8ac6cac..ada9be118a8 100644 --- a/dlls/itss/chm_lib.c +++ b/dlls/itss/chm_lib.c @@ -829,6 +829,38 @@ struct chmFile *chm_openW(const WCHAR *filename) return newHandle; } +/* Duplicate an ITS archive handle */ +struct chmFile *chm_dup(struct chmFile *oldHandle) +{ + struct chmFile *newHandle=NULL; + + newHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(struct chmFile)); + memcpy(newHandle, oldHandle, sizeof(struct chmFile)); + + /* duplicate fd handle */ + DuplicateHandle(GetCurrentProcess(), oldHandle->fd, + GetCurrentProcess(), &(newHandle->fd), + 0, FALSE, DUPLICATE_SAME_ACCESS); + newHandle->lzx_state = NULL; + newHandle->cache_blocks = NULL; + newHandle->cache_block_indices = NULL; + newHandle->cache_num_blocks = 0; + + /* initialize mutexes, if needed */ + InitializeCriticalSection(&newHandle->mutex); + newHandle->mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.mutex"); + InitializeCriticalSection(&newHandle->lzx_mutex); + newHandle->lzx_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.lzx_mutex"); + InitializeCriticalSection(&newHandle->cache_mutex); + newHandle->cache_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.cache_mutex"); + + /* initialize cache */ + chm_set_param(newHandle, CHM_PARAM_MAX_BLOCKS_CACHED, + CHM_MAX_BLOCKS_CACHED); + + return newHandle; +} + /* close an ITS archive */ void chm_close(struct chmFile *h) { diff --git a/dlls/itss/chm_lib.h b/dlls/itss/chm_lib.h index 0b3718c110b..fcd17b50cbf 100644 --- a/dlls/itss/chm_lib.h +++ b/dlls/itss/chm_lib.h @@ -73,6 +73,7 @@ struct chmUnitInfo }; struct chmFile* chm_openW(const WCHAR *filename); +struct chmFile *chm_dup(struct chmFile *oldHandle); /* close an ITS archive */ void chm_close(struct chmFile *h); diff --git a/dlls/itss/storage.c b/dlls/itss/storage.c index de0acfaee3e..fa92c4fb6de 100644 --- a/dlls/itss/storage.c +++ b/dlls/itss/storage.c @@ -391,10 +391,42 @@ static HRESULT WINAPI ITSS_IStorageImpl_OpenStorage( IStorage** ppstg) { ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface; + static const WCHAR szRoot[] = { '/', 0 }; + struct chmFile *chmfile; + WCHAR *path, *p; + DWORD len; - FIXME("%p %s %p %u %p %u %p\n", This, debugstr_w(pwcsName), + TRACE("%p %s %p %u %p %u %p\n", This, debugstr_w(pwcsName), pstgPriority, grfMode, snbExclude, reserved, ppstg); - return E_NOTIMPL; + + len = strlenW( This->dir ) + strlenW( pwcsName ) + 1; + path = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); + strcpyW( path, This->dir ); + + if( pwcsName[0] == '/' || pwcsName[0] == '\\' ) + { + p = &path[strlenW( path ) - 1]; + while( ( path <= p ) && ( *p == '/' ) ) + *p-- = 0; + } + strcatW( path, pwcsName ); + + for(p=path; *p; p++) { + if(*p == '\\') + *p = '/'; + } + + if(*--p == '/') + *p = 0; + + strcatW( path, szRoot ); + + TRACE("Resolving %s\n", debugstr_w(path)); + + chmfile = chm_dup( This->chmfile ); + if( !chmfile ) + return E_FAIL; + return ITSS_create_chm_storage(chmfile, path, ppstg); } static HRESULT WINAPI ITSS_IStorageImpl_CopyTo(