ReactOS 0.4.15-dev-7788-g1ad9096
DragDrop.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for Drag & Drop
5 * PROGRAMMER: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "shelltest.h"
9#include <shlwapi.h>
10
11#define NDEBUG
12#include <debug.h>
13#include <stdio.h>
14
15#define TESTFILENAME L"DragDropTest.txt"
16#define DROPPED_ON_FILE L"DragDroppedOn.lnk"
17
18static CComPtr<IShellFolder> s_pDesktop;
19
25
26enum OP
27{
35};
36
37#define D_NONE DROPEFFECT_NONE
38#define D_COPY DROPEFFECT_COPY
39#define D_MOVE DROPEFFECT_MOVE
40#define D_LINK DROPEFFECT_LINK
41#define D_NONE_OR_COPY 0xAABBCCDD
42#define D_NONE_OR_MOVE 0x11223344
43#define D_NONE_OR_LINK 0x55667788
44
45struct TEST_ENTRY
46{
47 int line;
55};
56
57static const TEST_ENTRY s_TestEntries[] =
58{
59 // MK_LBUTTON
60 { __LINE__, OP_NONE, S_OK, S_OK, MK_LBUTTON, D_NONE, D_NONE, D_NONE },
61 { __LINE__, OP_COPY, S_OK, S_OK, MK_LBUTTON, D_COPY, D_COPY, D_COPY },
62 { __LINE__, OP_MOVE, S_OK, S_OK, MK_LBUTTON, D_COPY | D_MOVE, D_MOVE, D_NONE },
63 { __LINE__, OP_MOVE, S_OK, S_OK, MK_LBUTTON, D_COPY | D_MOVE | D_LINK, D_MOVE, D_NONE },
64 { __LINE__, OP_COPY, S_OK, S_OK, MK_LBUTTON, D_COPY | D_LINK, D_COPY, D_COPY },
65 { __LINE__, OP_MOVE, S_OK, S_OK, MK_LBUTTON, D_MOVE, D_MOVE, D_NONE },
66 { __LINE__, OP_MOVE, S_OK, S_OK, MK_LBUTTON, D_MOVE | D_LINK, D_MOVE, D_NONE },
67 { __LINE__, OP_LINK, S_OK, S_OK, MK_LBUTTON, D_LINK, D_LINK, D_LINK },
68
69 // MK_LBUTTON | MK_SHIFT
70 { __LINE__, OP_NONE, S_OK, S_OK, MK_LBUTTON | MK_SHIFT, D_NONE, D_NONE, D_NONE },
75 { __LINE__, OP_MOVE, S_OK, S_OK, MK_LBUTTON | MK_SHIFT, D_MOVE, D_MOVE, D_NONE },
78
79 // MK_LBUTTON | MK_SHIFT | MK_CONTROL
80#define MK_LBUTTON_SHIFT_CTRL (MK_LBUTTON | MK_SHIFT | MK_CONTROL)
89#undef MK_LBUTTON_SHIFT_CTRL
90
91 // MK_LBUTTON | MK_CONTROL
100};
101
103{
104 FILE *fp = _wfopen(pszFileName, L"wb");
105 ok(fp != NULL, "fp is NULL for '%S'\n", pszFileName);
106 fclose(fp);
107}
108
110 LPCWSTR pszLnkFileName,
111 LPCWSTR pszTargetPathName)
112{
113 CComPtr<IPersistFile> ppf;
114 CComPtr<IShellLinkW> psl;
115 HRESULT hr;
116
117 hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
118 IID_IShellLinkW, (LPVOID *)&psl);
119 if (SUCCEEDED(hr))
120 {
121 psl->SetPath(pszTargetPathName);
122
123 hr = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
124 if (SUCCEEDED(hr))
125 {
126 hr = ppf->Save(pszLnkFileName, TRUE);
127 }
128 }
129
130 return hr;
131}
132
133static HRESULT
135{
136 *ppvOut = NULL;
137
138 LPCITEMIDLIST pidlLast;
139 CComPtr<IShellFolder> psf;
140 HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID *)&psf,
141 &pidlLast);
142 if (FAILED(hr))
143 return hr;
144
145 hr = psf->GetUIObjectOf(NULL, 1, &pidlLast, riid, NULL, ppvOut);
146 return hr;
147}
148
149static HRESULT
151{
152 *ppvOut = NULL;
153
154 PIDLIST_ABSOLUTE pidl = ILCreateFromPathW(pszPath);
155 if (!pidl)
156 return E_FAIL;
157
158 HRESULT hr = GetUIObjectOfAbsPidl(pidl, riid, ppvOut);
159
160 CoTaskMemFree(pidl);
161
162 return hr;
163}
164
166{
168 HANDLE hFind = FindFirstFileW(pszSpec, &find);
169 if (hFind != INVALID_HANDLE_VALUE)
170 {
171 FindClose(hFind);
172 return TRUE;
173 }
174 return FALSE;
175}
176
178{
179 WCHAR szPath[MAX_PATH], szFile[MAX_PATH];
180 lstrcpyW(szPath, pszSpec);
182
184 HANDLE hFind = FindFirstFileW(pszSpec, &find);
185 if (hFind != INVALID_HANDLE_VALUE)
186 {
187 do
188 {
189 lstrcpyW(szFile, szPath);
190 PathAppendW(szFile, find.cFileName);
191 DeleteFileW(szFile);
192 } while (FindNextFileW(hFind, &find));
193
194 FindClose(hFind);
195 }
196}
197
198static void DoTestEntry(const TEST_ENTRY *pEntry)
199{
200 int line = pEntry->line;
201 HRESULT hr;
202 PIDLIST_ABSOLUTE pidlDesktop = NULL;
203 CComPtr<IDropTarget> pDropTarget;
204 CComPtr<IDataObject> pDataObject;
205
206 // get the desktop PIDL
208 ok(!!pidlDesktop, "pidlDesktop is NULL\n");
209
210 // build paths
211 //
214
218
221
223 PathAppendW(s_szDestLinkSpec, L"*DragDropTest*.lnk");
224
225 //trace("s_szSrcTestFile: '%S'\n", s_szSrcTestFile);
226 //trace("s_szDestTestFile: '%S'\n", s_szDestTestFile);
227 //trace("s_szDestLinkSpec: '%S'\n", s_szDestLinkSpec);
228 //trace("s_szDroppedToItem: '%S'\n", s_szDroppedToItem);
229
230 // create or delete files
231 //
237
238 // check file existence
239 //
240 ok(PathIsDirectoryW(s_szDestFolder), "s_szDestFolder is not directory\n");
241 ok(PathFileExistsW(s_szSrcTestFile), "s_szSrcTestFile doesn't exist\n");
242 ok(!DoSpecExistsW(s_szDestLinkSpec), "s_szDestLinkSpec doesn't exist\n");
243 ok(!PathFileExistsW(s_szDestTestFile), "s_szDestTestFile exists\n");
244
245 // get an IDataObject
246 pDataObject = NULL;
248 ok_long(hr, S_OK);
249
250 // get an IDropTarget
251 CComPtr<IEnumIDList> pEnumIDList;
252 PIDLIST_ABSOLUTE pidl = NULL;
253 hr = s_pDesktop->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
254 &pEnumIDList);
255 ok_long(hr, S_OK);
256 while (pEnumIDList->Next(1, &pidl, NULL) == S_OK)
257 {
258 WCHAR szText[MAX_PATH];
259 SHGetPathFromIDListW(pidl, szText);
260 if (wcsstr(szText, DROPPED_ON_FILE) != NULL)
261 {
262 break;
263 }
264 CoTaskMemFree(pidl);
265 pidl = NULL;
266 }
267 ok(pidl != NULL, "Line %d: pidl is NULL\n", line);
268 pDropTarget = NULL;
269 PITEMID_CHILD pidlLast = ILFindLastID(pidl);
270 hr = s_pDesktop->GetUIObjectOf(NULL, 1, &pidlLast, IID_IDropTarget,
271 NULL, (LPVOID *)&pDropTarget);
272 CoTaskMemFree(pidl);
273 ok_long(hr, S_OK);
274
275 if (!pDropTarget)
276 {
277 skip("Line %d: pDropTarget was NULL\n", line);
278
279 // clean up
283 ILFree(pidlDesktop);
284
285 return;
286 }
287
288 // DragEnter
289 POINTL ptl = { 0, 0 };
290 DWORD dwKeyState = pEntry->dwKeyState;
291 DWORD dwEffects = pEntry->dwEffects1;
292 hr = pDropTarget->DragEnter(pDataObject, dwKeyState, ptl, &dwEffects);
293
294 ok(hr == pEntry->hr1, "Line %d: hr1 was %08lX\n", line, hr);
295
296 switch (pEntry->dwEffects2)
297 {
298 case D_NONE_OR_COPY:
299 ok((dwEffects == D_NONE || dwEffects == D_COPY),
300 "Line %d: dwEffects2 was %08lX\n", line, dwEffects);
301 break;
302 case D_NONE_OR_MOVE:
303 ok((dwEffects == D_NONE || dwEffects == D_MOVE),
304 "Line %d: dwEffects2 was %08lX\n", line, dwEffects);
305 break;
306 case D_NONE_OR_LINK:
307 ok((dwEffects == D_NONE || dwEffects == D_LINK),
308 "Line %d: dwEffects2 was %08lX\n", line, dwEffects);
309 break;
310 default:
311 ok(dwEffects == pEntry->dwEffects2,
312 "Line %d: dwEffects2 was %08lX\n", line, dwEffects);
313 break;
314 }
315
316 // Drop
317 hr = pDropTarget->Drop(pDataObject, dwKeyState, ptl, &dwEffects);
318 ok(hr == pEntry->hr2, "Line %d: hr2 was %08lX\n", line, hr);
319
320 switch (pEntry->dwEffects3)
321 {
322 case D_NONE_OR_COPY:
323 ok((dwEffects == D_NONE || dwEffects == D_COPY),
324 "Line %d: dwEffects3 was %08lX\n", line, dwEffects);
325 break;
326 case D_NONE_OR_MOVE:
327 ok((dwEffects == D_NONE || dwEffects == D_MOVE),
328 "Line %d: dwEffects3 was %08lX\n", line, dwEffects);
329 break;
330 case D_NONE_OR_LINK:
331 ok((dwEffects == D_NONE || dwEffects == D_LINK),
332 "Line %d: dwEffects3 was %08lX\n", line, dwEffects);
333 break;
334 default:
335 ok(dwEffects == pEntry->dwEffects3,
336 "Line %d: dwEffects3 was %08lX\n", line, dwEffects);
337 break;
338 }
339
340 // check file existence by pEntry->op
341 switch (pEntry->op)
342 {
343 case OP_NONE:
344 ok(PathFileExistsW(s_szSrcTestFile), "Line %d: src not exists\n", line);
345 ok(!PathFileExistsW(s_szDestTestFile), "Line %d: dest exists\n", line);
346 ok(!DoSpecExistsW(s_szDestLinkSpec), "Line %d: link exists\n", line);
347 break;
348 case OP_COPY:
349 ok(PathFileExistsW(s_szSrcTestFile), "Line %d: src not exists\n", line);
350 ok(PathFileExistsW(s_szDestTestFile), "Line %d: dest not exists\n", line);
351 ok(!DoSpecExistsW(s_szDestLinkSpec), "Line %d: link exists\n", line);
352 break;
353 case OP_MOVE:
354 ok(!PathFileExistsW(s_szSrcTestFile), "Line %d: src exists\n", line);
355 ok(PathFileExistsW(s_szDestTestFile), "Line %d: dest not exists\n", line);
356 ok(!DoSpecExistsW(s_szDestLinkSpec), "Line %d: link exists\n", line);
357 break;
358 case OP_LINK:
359 ok(PathFileExistsW(s_szSrcTestFile), "Line %d: src not exists\n", line);
360 ok(!PathFileExistsW(s_szDestTestFile), "Line %d: dest not exists\n", line);
361 ok(DoSpecExistsW(s_szDestLinkSpec), "Line %d: link not exists\n", line);
362 break;
363 case OP_NONE_OR_COPY:
364 ok(PathFileExistsW(s_szSrcTestFile), "Line %d: src not exists\n", line);
365 ok(!DoSpecExistsW(s_szDestLinkSpec), "Line %d: link exists\n", line);
366 break;
367 case OP_NONE_OR_MOVE:
369 "Line %d: It must be either None or Move\n", line);
370 break;
371 case OP_NONE_OR_LINK:
372 ok(PathFileExistsW(s_szSrcTestFile), "Line %d: src not exists\n", line);
373 ok(!PathFileExistsW(s_szDestTestFile), "Line %d: dest not exists\n", line);
374 break;
375 }
376
377 // clean up
381 ILFree(pidlDesktop);
382}
383
384START_TEST(DragDrop)
385{
387 {
388 skip("Skipping the test due to crash. CORE-17057\n");
389 return;
390 }
391
394
396 ok(!!s_pDesktop, "s_pDesktop is NULL\n");
397
399 ok_int(ret, TRUE);
400
401 for (size_t i = 0; i < _countof(s_TestEntries); ++i)
402 {
404 }
405
410
412}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
static void DoCreateTestFile(LPCWSTR pszFileName)
Definition: DragDrop.cpp:102
void DoDeleteSpecW(LPCWSTR pszSpec)
Definition: DragDrop.cpp:177
#define D_NONE_OR_COPY
Definition: DragDrop.cpp:41
static WCHAR s_szDestFolder[MAX_PATH]
Definition: DragDrop.cpp:21
static void DoTestEntry(const TEST_ENTRY *pEntry)
Definition: DragDrop.cpp:198
#define D_NONE
Definition: DragDrop.cpp:37
static WCHAR s_szDroppedToItem[MAX_PATH]
Definition: DragDrop.cpp:24
static WCHAR s_szDestTestFile[MAX_PATH]
Definition: DragDrop.cpp:22
#define MK_LBUTTON_SHIFT_CTRL
#define D_COPY
Definition: DragDrop.cpp:38
static WCHAR s_szDestLinkSpec[MAX_PATH]
Definition: DragDrop.cpp:23
static HRESULT GetUIObjectOfAbsPidl(PIDLIST_ABSOLUTE pidl, REFIID riid, LPVOID *ppvOut)
Definition: DragDrop.cpp:134
#define D_MOVE
Definition: DragDrop.cpp:39
static HRESULT GetUIObjectOfPath(LPCWSTR pszPath, REFIID riid, LPVOID *ppvOut)
Definition: DragDrop.cpp:150
static WCHAR s_szSrcTestFile[MAX_PATH]
Definition: DragDrop.cpp:20
#define TESTFILENAME
Definition: DragDrop.cpp:15
#define DROPPED_ON_FILE
Definition: DragDrop.cpp:16
HRESULT DoCreateShortcut(LPCWSTR pszLnkFileName, LPCWSTR pszTargetPathName)
Definition: DragDrop.cpp:109
#define D_LINK
Definition: DragDrop.cpp:40
#define D_NONE_OR_LINK
Definition: DragDrop.cpp:43
BOOL DoSpecExistsW(LPCWSTR pszSpec)
Definition: DragDrop.cpp:165
#define D_NONE_OR_MOVE
Definition: DragDrop.cpp:42
static const TEST_ENTRY s_TestEntries[]
Definition: DragDrop.cpp:57
static CComPtr< IShellFolder > s_pDesktop
Definition: DragDrop.cpp:18
OP
Definition: DragDrop.cpp:27
@ OP_NONE_OR_MOVE
Definition: DragDrop.cpp:33
@ OP_NONE
Definition: DragDrop.cpp:28
@ OP_COPY
Definition: DragDrop.cpp:29
@ OP_LINK
Definition: DragDrop.cpp:31
@ OP_MOVE
Definition: DragDrop.cpp:30
@ OP_NONE_OR_COPY
Definition: DragDrop.cpp:32
@ OP_NONE_OR_LINK
Definition: DragDrop.cpp:34
#define ok_long(expression, result)
Definition: atltest.h:133
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
static TAGID TAGID find
Definition: db.cpp:155
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3194
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3061
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1723
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
REFIID riid
Definition: atlbase.h:39
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
LPCWSTR szPath
Definition: env.c:37
#define L(x)
Definition: ntvdm.h:50
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
const GUID IID_IDataObject
const GUID IID_IPersistFile
#define PathAppendW
Definition: pathcch.h:309
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:929
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:189
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1352
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1344
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:986
#define REFIID
Definition: guiddef.h:118
int winetest_interactive
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_DESKTOP
Definition: shlobj.h:2158
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:68
Definition: cmd.c:13
INT line
Definition: cmd.c:14
DWORD dwEffects1
Definition: DragDrop.cpp:52
HRESULT hr1
Definition: DragDrop.cpp:49
DWORD dwEffects3
Definition: DragDrop.cpp:54
OP op
Definition: DragDrop.cpp:48
DWORD dwEffects2
Definition: DragDrop.cpp:53
DWORD dwKeyState
Definition: DragDrop.cpp:51
HRESULT hr2
Definition: DragDrop.cpp:50
Definition: parser.c:49
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
int ret
#define MK_SHIFT
Definition: winuser.h:2369
#define MK_CONTROL
Definition: winuser.h:2370
#define MK_LBUTTON
Definition: winuser.h:2367
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185