Console compiles on UNIX with UNICODE
[public/netxms.git] / src / libnxcl / image.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Client Library
4 ** Copyright (C) 2004, 2005, 2006, 2007 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** File: image.cpp
21 **
22 **/
23
24 #include "libnxcl.h"
25
26
27 //
28 // Download image file from server
29 //
30
31 DWORD LIBNXCL_EXPORTABLE NXCLoadImageFile(NXC_SESSION hSession, DWORD dwImageId,
32 TCHAR *pszCacheDir, WORD wFormat)
33 {
34 DWORD i, dwRqId, dwRetCode, dwFileSize, dwNumBytes;
35 CSCPMessage msg, *pResponse;
36 BYTE *pBuffer;
37 TCHAR cLastChar, szFileName[MAX_PATH];
38 FILE *hFile;
39
40 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
41
42 msg.SetCode(CMD_LOAD_IMAGE_FILE);
43 msg.SetId(dwRqId);
44 msg.SetVariable(VID_IMAGE_ID, dwImageId);
45 msg.SetVariable(VID_IMAGE_FORMAT, wFormat);
46 ((NXCL_Session *)hSession)->SendMsg(&msg);
47
48 // Loading file can take time, so we use 60 sec. timeout instead of default
49 pResponse = ((NXCL_Session *)hSession)->WaitForMessage(CMD_IMAGE_FILE, dwRqId, 60000);
50 if (pResponse != NULL)
51 {
52 dwRetCode = pResponse->GetVariableLong(VID_RCC);
53 if (dwRetCode == RCC_SUCCESS)
54 {
55 dwFileSize = pResponse->GetVariableLong(VID_IMAGE_FILE_SIZE);
56 pBuffer = (BYTE *)malloc(dwFileSize);
57 if (pBuffer != NULL)
58 {
59 pResponse->GetVariableBinary(VID_IMAGE_FILE, pBuffer, dwFileSize);
60 cLastChar = pszCacheDir[_tcslen(pszCacheDir) - 1];
61 _sntprintf(szFileName, MAX_PATH, _T("%s%s%08x.%s"), pszCacheDir,
62 (cLastChar == _T('\\')) || (cLastChar == _T('/')) ? _T("") : FS_PATH_SEPARATOR,
63 dwImageId, (wFormat == IMAGE_FORMAT_PNG) ? _T("png") : _T("ico"));
64 #ifndef _WIN32
65 //umask(0ïîòîì_ïîñ÷èòàþ);
66 #endif
67 hFile = _tfopen(szFileName, _T("wb"));
68 if (hFile != NULL)
69 {
70 for(i = 0; i < dwFileSize; i += dwNumBytes)
71 {
72 dwNumBytes = min(16384, dwFileSize - i);
73 fwrite(&pBuffer[i], 1, dwNumBytes, hFile);
74 }
75 fclose(hFile);
76 }
77 else
78 {
79 dwRetCode = RCC_IO_ERROR;
80 }
81 free(pBuffer);
82 }
83 else
84 {
85 dwRetCode = RCC_OUT_OF_MEMORY;
86 }
87 }
88 delete pResponse;
89 }
90 else
91 {
92 dwRetCode = RCC_TIMEOUT;
93 }
94
95 return dwRetCode;
96 }
97
98
99 //
100 // Synchronize single image file
101 //
102
103 static DWORD SyncImageFile(NXC_SESSION hSession, TCHAR *pszCacheDir,
104 DWORD dwImageId, BYTE *pServerHash, WORD wFormat)
105 {
106 TCHAR szFileName[MAX_PATH];
107 BYTE hash[MD5_DIGEST_SIZE];
108 DWORD dwRetCode = RCC_SUCCESS;
109
110 _sntprintf(szFileName, MAX_PATH, _T("%s") FS_PATH_SEPARATOR _T("%08x.%s"), pszCacheDir, dwImageId,
111 (wFormat == IMAGE_FORMAT_PNG) ? _T("png") : _T("ico"));
112 memset(hash, 0, MD5_DIGEST_SIZE);
113 CalculateFileMD5Hash(szFileName, hash);
114 if (memcmp(hash, pServerHash, MD5_DIGEST_SIZE))
115 // Hash not match, need to download file
116 dwRetCode = NXCLoadImageFile(hSession, dwImageId, pszCacheDir, wFormat);
117 return dwRetCode;
118 }
119
120
121 //
122 // Synchronize images with client
123 //
124
125 DWORD LIBNXCL_EXPORTABLE NXCSyncImages(NXC_SESSION hSession, NXC_IMAGE_LIST **ppImageList,
126 TCHAR *pszCacheDir, WORD wFormat)
127 {
128 DWORD i, dwRqId, dwRetCode, dwId;
129 CSCPMessage msg, *pResponse;
130
131 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
132
133 msg.SetCode(CMD_GET_IMAGE_LIST);
134 msg.SetId(dwRqId);
135 msg.SetVariable(VID_IMAGE_FORMAT, wFormat);
136 ((NXCL_Session *)hSession)->SendMsg(&msg);
137
138 pResponse = ((NXCL_Session *)hSession)->WaitForMessage(CMD_IMAGE_LIST, dwRqId,
139 ((NXCL_Session *)hSession)->m_dwCommandTimeout * 2);
140 if (pResponse != NULL)
141 {
142 dwRetCode = pResponse->GetVariableLong(VID_RCC);
143 if (dwRetCode == RCC_SUCCESS)
144 {
145 *ppImageList = (NXC_IMAGE_LIST *)malloc(sizeof(NXC_IMAGE_LIST));
146 (*ppImageList)->dwNumImages = pResponse->GetVariableLong(VID_NUM_IMAGES);
147 if ((*ppImageList)->dwNumImages > 0)
148 {
149 (*ppImageList)->pImageList = (NXC_IMAGE *)malloc(sizeof(NXC_IMAGE) * (*ppImageList)->dwNumImages);
150 for(i = 0, dwId = VID_IMAGE_LIST_BASE; i < (*ppImageList)->dwNumImages; i++, dwId += 7)
151 {
152 (*ppImageList)->pImageList[i].dwId = pResponse->GetVariableLong(dwId++);
153 pResponse->GetVariableStr(dwId++, (*ppImageList)->pImageList[i].szName, MAX_OBJECT_NAME);
154 pResponse->GetVariableBinary(dwId++, (*ppImageList)->pImageList[i].hash, MD5_DIGEST_SIZE);
155 dwRetCode = SyncImageFile(hSession, pszCacheDir,
156 (*ppImageList)->pImageList[i].dwId,
157 (*ppImageList)->pImageList[i].hash, wFormat);
158 if (dwRetCode != RCC_SUCCESS)
159 {
160 NXCDestroyImageList(*ppImageList);
161 break;
162 }
163 }
164 }
165 else
166 {
167 (*ppImageList)->pImageList = NULL;
168 }
169 }
170 delete pResponse;
171 }
172 else
173 {
174 dwRetCode = RCC_TIMEOUT;
175 }
176
177 return dwRetCode;
178 }
179
180
181 //
182 // Destroy image list
183 //
184
185 void LIBNXCL_EXPORTABLE NXCDestroyImageList(NXC_IMAGE_LIST *pImageList)
186 {
187 if (pImageList != NULL)
188 {
189 safe_free(pImageList->pImageList);
190 free(pImageList);
191 }
192 }
193
194
195 //
196 // Load default image list
197 //
198
199 DWORD LIBNXCL_EXPORTABLE NXCLoadDefaultImageList(NXC_SESSION hSession, DWORD *pdwListSize,
200 DWORD **ppdwClassId, DWORD **ppdwImageId)
201 {
202 CSCPMessage msg, *pResponse;
203 DWORD dwRetCode, dwRqId;
204
205 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
206
207 msg.SetCode(CMD_GET_DEFAULT_IMAGE_LIST);
208 msg.SetId(dwRqId);
209 ((NXCL_Session *)hSession)->SendMsg(&msg);
210
211 pResponse = ((NXCL_Session *)hSession)->WaitForMessage(CMD_DEFAULT_IMAGE_LIST, dwRqId);
212 if (pResponse != NULL)
213 {
214 dwRetCode = pResponse->GetVariableLong(VID_RCC);
215 if (dwRetCode == RCC_SUCCESS)
216 {
217 *pdwListSize = pResponse->GetVariableLong(VID_NUM_IMAGES);
218 *ppdwClassId = (DWORD *)malloc(sizeof(DWORD) * *pdwListSize);
219 *ppdwImageId = (DWORD *)malloc(sizeof(DWORD) * *pdwListSize);
220 pResponse->GetVariableInt32Array(VID_CLASS_ID_LIST, *pdwListSize, *ppdwClassId);
221 pResponse->GetVariableInt32Array(VID_IMAGE_ID_LIST, *pdwListSize, *ppdwImageId);
222 }
223 delete pResponse;
224 }
225 else
226 {
227 dwRetCode = RCC_TIMEOUT;
228 }
229 return dwRetCode;
230 }