1 #include "RKDevice.h"
2
3 const tchar *szManufName[] =
4 {
5 _T("SAMSUNG"),
6 _T("TOSHIBA"),
7 _T("HYNIX"),
8 _T("INFINEON"),
9 _T("MICRON"),
10 _T("RENESAS"),
11 _T("ST"),
12 _T("INTEL")
13 };
14
SetPrepareEraseFlag(bool value)15 void CRKDevice::SetPrepareEraseFlag(bool value)
16 {
17 m_bEraseInPrepare = value;
18 }
19
SetWorkFlow(UINT value)20 void CRKDevice::SetWorkFlow(UINT value)
21 {
22 m_uiWorkFlow = value;
23 }
24
SetUid(PBYTE value)25 void CRKDevice::SetUid(PBYTE value)
26 {
27 if (value)
28 {
29 if (!m_uid)
30 {
31 m_uid = new BYTE[RKDEVICE_UID_LEN];
32 memset(m_uid, 0, RKDEVICE_UID_LEN);
33 }
34 memcpy(m_uid, value, RKDEVICE_UID_LEN);
35 }
36 else
37 {
38 if (m_uid)
39 {
40 delete []m_uid;
41 }
42 m_uid = value;
43 }
44 }
SetMiscModifyFlag(ENUM_MISC_MODIFY_FLAG value)45 void CRKDevice::SetMiscModifyFlag(ENUM_MISC_MODIFY_FLAG value)
46 {
47 m_emMiscModifyFlag = value;
48 }
49
SetOsType(ENUM_OS_TYPE value)50 void CRKDevice::SetOsType(ENUM_OS_TYPE value)
51 {
52 m_os = value;
53 }
GetOsType()54 ENUM_OS_TYPE CRKDevice::GetOsType()
55 {
56 return m_os;
57 }
58
GetLogObjectPointer()59 CRKLog *CRKDevice::GetLogObjectPointer()
60 {
61 return m_pLog;
62 }
63
GetCommObjectPointer()64 CRKComm *CRKDevice::GetCommObjectPointer()
65 {
66 return m_pComm;
67 }
68
CRKDevice(STRUCT_RKDEVICE_DESC & device)69 CRKDevice::CRKDevice(STRUCT_RKDEVICE_DESC &device)
70 {
71 OsType.setContainer(this);
72 OsType.getter(&CRKDevice::GetOsType);
73 OsType.setter(&CRKDevice::SetOsType);
74
75 Uid.setContainer(this);
76 Uid.setter(&CRKDevice::SetUid);
77
78 PrepareEraseFlag.setContainer(this);
79 PrepareEraseFlag.setter(&CRKDevice::SetPrepareEraseFlag);
80
81 WorkFlow.setContainer(this);
82 WorkFlow.setter(&CRKDevice::SetWorkFlow);
83
84 MiscModifyFlag.setContainer(this);
85 MiscModifyFlag.setter(&CRKDevice::SetMiscModifyFlag);
86
87 LogObjectPointer.setContainer(this);
88 LogObjectPointer.getter(&CRKDevice::GetLogObjectPointer);
89
90 CommObjectPointer.setContainer(this);
91 CommObjectPointer.getter(&CRKDevice::GetCommObjectPointer);
92
93 m_usb = device.emUsbType;
94 m_device = device.emDeviceType;
95 m_bcdUsb = device.usbcdUsb;
96
97 memset(m_idBlockOffset, 0, sizeof(DWORD) * 5);
98 memset(m_flashInfo.blockState, 0, IDBLOCK_TOP);
99 m_flashInfo.usPhyBlokcPerIDB = 1;
100 m_flashInfo.uiSecNumPerIDB = 0;
101 m_chipData = NULL;
102 m_pImage = NULL;
103 m_pLog = NULL;
104 m_pComm = NULL;
105 m_customData = NULL;
106 m_customDataSize = 0;
107 m_customDataOffset = 0;
108 m_sn = NULL;
109 m_snSize = 0;
110 m_mac = NULL;
111 m_imei = NULL;
112 m_blueTooth = NULL;
113 m_uid = NULL;
114 m_sysDiskSize = 0;
115 m_cfgDiskSize = 0;
116 m_bGetNewDiskSizeFlag = true;
117 m_pBlockState = NULL;
118 m_bWriteBack = false;
119 m_pFlashInfoData = NULL;
120 m_usFlashInfoDataLen = 0;
121 m_usFlashInfoDataOffset = 0;
122 memset(m_backupBuffer, 0, SECTOR_SIZE);
123 memset(m_backupBuffer + SECTOR_SIZE, 0xFF, SPARE_SIZE);
124 m_bUidWriteOK = false;
125 m_remallocDisk = false;
126 m_emMiscModifyFlag = MISC_MODIFY_NONE;
127 m_bQuickCheckMode = false;
128 m_bExistSector3Crc = false;
129 m_bEmmc = false;
130 m_usSector3Crc = 0;
131 m_usWriteBackCrc = 0;
132 m_usWriteBackCustomDataOffset = 0;
133 m_usWriteBackCustomDataSize = 0;
134 }
~CRKDevice()135 CRKDevice::~CRKDevice()
136 {
137 if (m_pComm)
138 {
139 delete m_pComm;
140 m_pComm = NULL;
141 }
142 if (m_chipData)
143 {
144 delete []m_chipData;
145 m_chipData = NULL;
146 }
147 if (m_customData)
148 {
149 delete []m_customData;
150 m_customData = NULL;
151 }
152 if (m_sn)
153 {
154 delete []m_sn;
155 m_sn = NULL;
156 }
157 if (m_mac)
158 {
159 delete []m_mac;
160 m_mac = NULL;
161 }
162 if (m_imei)
163 {
164 delete []m_imei;
165 m_imei = NULL;
166 }
167 if (m_blueTooth)
168 {
169 delete []m_blueTooth;
170 m_blueTooth = NULL;
171 }
172 if (m_uid)
173 {
174 delete []m_uid;
175 m_uid = NULL;
176 }
177
178 if (m_pFlashInfoData)
179 {
180 delete []m_pFlashInfoData;
181 m_pFlashInfoData = NULL;
182 }
183 }
184
SetObject(CRKImage * pImage,CRKComm * pComm,CRKLog * pLog)185 bool CRKDevice::SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog)
186 {
187 /*pImage����Ϊ��,������ɲ��ù̼�����IJ���*/
188 if (!pComm)
189 {
190 return false;
191 }
192 m_pImage = pImage;
193 m_pComm = pComm;
194 m_pLog = pLog;
195 if (m_pImage)
196 {
197 m_os = m_pImage->OsType;
198 }
199 else
200 {
201 m_os = RK_OS;
202 }
203 return true;
204 }
EraseEmmcBlock(UCHAR ucFlashCS,DWORD dwPos,DWORD dwCount)205 int CRKDevice::EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount)
206 {
207 int sectorOffset, nWrittenBlcok, iRet;
208 BYTE emptyData[4 * (SECTOR_SIZE + SPARE_SIZE)];
209 memset(emptyData, 0xff, 4 * (SECTOR_SIZE + SPARE_SIZE));
210 nWrittenBlcok = 0;
211 while (dwCount > 0)
212 {
213 sectorOffset = (ucFlashCS * m_flashInfo.uiBlockNum + dwPos + nWrittenBlcok) * m_flashInfo.uiSectorPerBlock;
214 iRet = m_pComm->RKU_WriteSector(sectorOffset, 4, emptyData);
215 if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK))
216 {
217 if (m_pLog)
218 {
219 m_pLog->Record(_T("ERROR:EraseEmmcBlock-->RKU_WriteSector failed,RetCode(%d)"), iRet);
220 }
221 return iRet;
222 }
223 dwCount--;
224 nWrittenBlcok++;
225 }
226 return ERR_SUCCESS;
227 }
GetFlashInfo()228 bool CRKDevice::GetFlashInfo()
229 {
230 STRUCT_FLASHINFO_CMD info;
231 BYTE flashID[5];
232 int iRet;
233 UINT uiRead;
234 iRet = m_pComm->RKU_ReadFlashInfo((PBYTE)&info, &uiRead);
235 if (ERR_SUCCESS == iRet)
236 {
237 if (m_pLog)
238 {
239 tstring strFlashInfo;
240 m_pLog->PrintBuffer(strFlashInfo, (PBYTE)&info, 11);
241 m_pLog->Record(_T("INFO:FlashInfo:%s"), strFlashInfo.c_str());
242 }
243
244 #if 0 //closed by chad.ma
245 if ((info.usBlockSize == 0) || (info.bPageSize == 0))
246 {
247 if (m_pLog)
248 {
249 m_pLog->Record(_T("ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,pagesize or blocksize is zero"));
250 }
251 return false;
252 }
253 if ((info.bManufCode >= 0) && (info.bManufCode <= 7))
254 {
255 _tcscpy(m_flashInfo.szManufacturerName, szManufName[info.bManufCode]);
256 }
257 else
258 {
259 _tcscpy(m_flashInfo.szManufacturerName, _T("UNKNOWN"));
260 }
261 #endif
262
263 //m_flashInfo.uiFlashSize = info.uiFlashSize/2/1024;//MB
264 m_flashInfo.uiFlashSize = info.uiFlashSize / 1024;//MB
265 m_flashInfo.uiBlockNum = info.uiFlashSize * 2;
266 printf("%s: %d info.uiFlashSize = %d total uiBlockNum = %d\n", __func__, __LINE__, info.uiFlashSize, m_flashInfo.uiBlockNum);
267 printf("%s: %d FlashSize = %d MB\n", __func__, __LINE__, m_flashInfo.uiFlashSize);
268
269 #if 0 //closed by chad.ma
270 m_flashInfo.uiPageSize = info.bPageSize / 2; //KB
271 m_flashInfo.usBlockSize = info.usBlockSize / 2; //KB
272 m_flashInfo.bECCBits = info.bECCBits;
273 m_flashInfo.bAccessTime = info.bAccessTime;
274 m_flashInfo.uiBlockNum = m_flashInfo.uiFlashSize * 1024 / m_flashInfo.usBlockSize;
275 m_flashInfo.uiSectorPerBlock = info.usBlockSize;
276 m_flashInfo.bFlashCS = info.bFlashCS;
277 m_flashInfo.usValidSecPerBlock = (info.usBlockSize / info.bPageSize) * 4;
278 if (m_pFlashInfoData)
279 {
280 delete []m_pFlashInfoData;
281 m_pFlashInfoData = NULL;
282 }
283 m_usFlashInfoDataLen = BYTE2SECTOR(uiRead);
284 m_pFlashInfoData = new BYTE[SECTOR_SIZE * m_usFlashInfoDataLen];
285 memset(m_pFlashInfoData, 0, SECTOR_SIZE * m_usFlashInfoDataLen);
286 memcpy(m_pFlashInfoData, (PBYTE)&info, uiRead);
287 #endif
288 }
289 else
290 {
291 if (m_pLog)
292 {
293 m_pLog->Record(_T("ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,RetCode(%d)"), iRet);
294 }
295
296 return false;
297 }
298 return true;
299 }
BuildBlockStateMap(BYTE bFlashCS)300 bool CRKDevice::BuildBlockStateMap(BYTE bFlashCS)
301 {
302 BYTE blockState[64];
303 int iRet, i, j ;
304 memset(blockState, 0, 64);
305 iRet = m_pComm->RKU_TestBadBlock(bFlashCS, 0, MAX_TEST_BLOCKS, blockState);
306 if (ERR_SUCCESS == iRet) //����
307 {
308 // return true;
309 // }
310 // else if(ERR_FOUND_BAD_BLOCK == iRet)//���
311 // {
312 for (i = 0; i < 64; i++)
313 {
314 for (j = 0; j < 8; j++)
315 {
316 if (blockState[i] & (1 << j))
317 {
318 m_flashInfo.blockState[i * 8 + j] = 1;
319 }
320 if (i * 8 + j > (IDBLOCK_TOP - 2))
321 {
322 break;
323 }
324 }
325 if (j < 8)
326 {
327 break;
328 }
329 }
330 return true;
331 }
332 else//����ʧ��
333 {
334 if (m_pLog)
335 {
336 m_pLog->Record(_T("ERROR:BuildBlockStateMap-->RKU_TestBadBlock failed,RetCode(%d)"), iRet);
337 }
338 return false;
339 }
340 }
ReadMutilSector(DWORD dwPos,DWORD dwCount,PBYTE lpBuffer)341 int CRKDevice::ReadMutilSector(DWORD dwPos, DWORD dwCount, PBYTE lpBuffer)
342 {
343 DWORD dwReadSector = 0, dwMaxReadWriteOnce;
344 int iUsedSecCount, iUsedBlockCount, iValidSecCount;
345 int iRet = 0, iCurPos;
346 iUsedBlockCount = dwPos / m_flashInfo.uiSectorPerBlock;
347 iUsedSecCount = dwPos - (iUsedBlockCount * m_flashInfo.uiSectorPerBlock);
348 iValidSecCount = m_flashInfo.usValidSecPerBlock - iUsedSecCount;
349
350 dwMaxReadWriteOnce = MAX_WRITE_SECTOR;
351
352 while (dwCount > 0)
353 {
354 dwReadSector = (dwCount >= dwMaxReadWriteOnce) ? dwMaxReadWriteOnce : dwCount;
355 if (dwReadSector > iValidSecCount)
356 {
357 dwReadSector = iValidSecCount;
358 }
359 iCurPos = iUsedBlockCount * m_flashInfo.uiSectorPerBlock + (m_flashInfo.usValidSecPerBlock - iValidSecCount);
360 iRet = m_pComm->RKU_ReadSector(iCurPos, dwReadSector, lpBuffer);
361 if (iRet != ERR_SUCCESS)
362 {
363 if (m_pLog)
364 {
365 m_pLog->Record(_T("ERROR:ReadMutilSector-->RKU_ReadSector failed,RetCode(%d)"), iRet);
366 }
367 break;
368 }
369
370 dwCount -= dwReadSector;
371 iUsedSecCount += dwReadSector;
372 iValidSecCount -= dwReadSector;
373 if (iValidSecCount <= 0)
374 {
375 iUsedBlockCount++;
376 iValidSecCount = m_flashInfo.usValidSecPerBlock;
377 }
378 lpBuffer += dwReadSector * 512;
379 }
380 return iRet;
381 }
EraseMutilBlock(BYTE bFlashCS,DWORD dwPos,DWORD dwCount,bool bForce)382 bool CRKDevice::EraseMutilBlock(BYTE bFlashCS, DWORD dwPos, DWORD dwCount, bool bForce)
383 {
384 DWORD dwTimes = 0;
385 UCHAR eraseType;
386 eraseType = bForce ? ERASE_FORCE : ERASE_NORMAL;
387 int iRet;
388 while (dwCount >= MAX_ERASE_BLOCKS)
389 {
390 iRet = m_pComm->RKU_EraseBlock(bFlashCS, dwPos + dwTimes * MAX_ERASE_BLOCKS, MAX_ERASE_BLOCKS, eraseType);
391 if (ERR_FOUND_BAD_BLOCK == iRet)
392 {
393 dwCount -= MAX_ERASE_BLOCKS;
394 ++dwTimes;
395 }
396 else if (ERR_SUCCESS == iRet)
397 {
398 dwCount -= MAX_ERASE_BLOCKS;
399 ++dwTimes;
400 }
401 else
402 {
403 //����ʧ��
404 if (m_pLog)
405 {
406 m_pLog->Record(_T("ERROR:EraseMutilBlock-->RKU_EraseBlock failed,RetCode(%d)"), iRet);
407 }
408 return false;
409 }
410 }
411 if (dwCount > 0)
412 {
413 iRet = m_pComm->RKU_EraseBlock(bFlashCS, dwPos + dwTimes * MAX_ERASE_BLOCKS, dwCount, eraseType);
414 if (ERR_SUCCESS == iRet)
415 {
416 dwCount = 0;
417 }
418 else if (ERR_FOUND_BAD_BLOCK == iRet)
419 {
420 dwCount = 0;
421 }
422 else
423 {
424 //����ʧ��
425 if (m_pLog)
426 {
427 m_pLog->Record(_T("ERROR:EraseMutilBlock-->RKU_EraseBlock failed,RetCode(%d)"), iRet);
428 }
429 return false;
430 }
431 }
432 return true;
433 }
434
435
CheckChip()436 bool CRKDevice::CheckChip()
437 {
438 int iRet;
439 BYTE bChipInfo[CHIPINFO_LEN];
440 ENUM_RKDEVICE_TYPE curDeviceType = RKNONE_DEVICE;
441 memset(bChipInfo, 0, CHIPINFO_LEN);
442 iRet = m_pComm->RKU_ReadChipInfo(bChipInfo);
443 if (iRet == ERR_SUCCESS)
444 {
445 if (!m_chipData)
446 {
447 m_chipData = new BYTE[CHIPINFO_LEN];
448 }
449 memset(m_chipData, 0, CHIPINFO_LEN);
450 memcpy(m_chipData, bChipInfo, CHIPINFO_LEN);
451 DWORD *pValue;
452 pValue = (DWORD *)(&bChipInfo[0]);
453
454 if ((ENUM_RKDEVICE_TYPE)(*pValue) == m_device)
455 {
456 return true;
457 }
458
459 if (*pValue == 0x524B3237)
460 {
461 curDeviceType = RK27_DEVICE;
462 }
463 else if (*pValue == 0x32373341)
464 {
465 curDeviceType = RKCAYMAN_DEVICE;
466 }
467 else if (*pValue == 0x524B3238)
468 {
469 curDeviceType = RK28_DEVICE;
470 }
471 else if (*pValue == 0x32383158)
472 {
473 curDeviceType = RK281X_DEVICE;
474 }
475 else if (*pValue == 0x32383242)
476 {
477 curDeviceType = RKPANDA_DEVICE;
478 }
479 else if (*pValue == 0x32393058)
480 {
481 curDeviceType = RK29_DEVICE;
482 }
483 else if (*pValue == 0x32393258)
484 {
485 curDeviceType = RK292X_DEVICE;
486 }
487 else if (*pValue == 0x33303041)
488 {
489 curDeviceType = RK30_DEVICE;
490 }
491 else if (*pValue == 0x33313041)
492 {
493 curDeviceType = RK30B_DEVICE;
494 }
495 else if (*pValue == 0x33313042)
496 {
497 curDeviceType = RK31_DEVICE;
498 }
499 else if (*pValue == 0x33323041)
500 {
501 curDeviceType = RK32_DEVICE;
502 }
503 else if (*pValue == 0x32363243)
504 {
505 curDeviceType = RKSMART_DEVICE;
506 }
507 else if (*pValue == 0x6E616E6F)
508 {
509 curDeviceType = RKNANO_DEVICE;
510 }
511 else if (*pValue == 0x4E4F5243)
512 {
513 curDeviceType = RKCROWN_DEVICE;
514 }
515
516 if (curDeviceType == m_device)
517 {
518 return true;
519 }
520 else
521 {
522 if (m_pLog)
523 {
524 m_pLog->Record(_T("ERROR:CheckChip-->Chip is not match,firmware(0x%x),device(0x%x)"), m_device, *pValue);
525 }
526 return false;
527 }
528 }
529 else
530 {
531 if (m_pLog)
532 {
533 m_pLog->Record(_T("ERROR:CheckChip-->RKU_ReadChipInfo failed,RetCode(%d)"), iRet);
534 }
535 return false;
536 }
537 }
FindValidBlocks(char bBegin,char bLen)538 CHAR CRKDevice::FindValidBlocks(char bBegin, char bLen)
539 {
540 char bCount = 0;
541 char bIndex = bBegin;
542 while (bBegin < IDBLOCK_TOP)
543 {
544 if (0 == m_flashInfo.blockState[bBegin++])
545 {
546 ++bCount;
547 }
548 else
549 {
550 bCount = 0;
551 bIndex = bBegin;
552 }
553 if (bCount >= bLen)
554 {
555 break;
556 }
557 }
558 if (bBegin >= IDBLOCK_TOP)
559 {
560 bIndex = -1;
561 }
562
563 return bIndex;
564 }
UshortToBCD(USHORT num)565 USHORT UshortToBCD(USHORT num)
566 {
567 USHORT bcd = 0;
568 bcd = (num % 10) | (((num / 10) % 10) << 4) | (((num / 100) % 10) << 8) | (((num / 1000) % 10) << 12);
569 return bcd;
570 }
ByteToBCD(BYTE num)571 BYTE ByteToBCD(BYTE num)
572 {
573 BYTE bcd = 0;
574 bcd = (num % 10) | (((num / 10) % 10) << 4);
575 return bcd;
576 }
RandomByte(BYTE bLowLimit,BYTE bHighLimit)577 BYTE CRKDevice::RandomByte(BYTE bLowLimit, BYTE bHighLimit)
578 {
579 BYTE k;
580 double d;
581
582 d = (double)rand() / ((double)RAND_MAX + 1);
583 k = (BYTE)(d * (bHighLimit - bLowLimit + 1));
584 return (bLowLimit + k);
585 }
CheckCrc16(PBYTE pCheckData,USHORT usDataLength,USHORT usOldCrc)586 bool CRKDevice::CheckCrc16(PBYTE pCheckData, USHORT usDataLength, USHORT usOldCrc)
587 {
588 USHORT usNewCrc;
589 usNewCrc = CRC_16(pCheckData, usDataLength);
590 return (usNewCrc == usOldCrc) ? true : false;
591 }
CheckUid(BYTE uidSize,BYTE * pUid)592 bool CRKDevice::CheckUid(BYTE uidSize, BYTE *pUid)
593 {
594 if (uidSize != RKDEVICE_UID_LEN)
595 {
596 return false;
597 }
598 USHORT oldCrc, newCrc;
599 oldCrc = *(USHORT *)(pUid + RKDEVICE_UID_LEN - 2);
600 newCrc = CRC_CCITT(pUid, RKDEVICE_UID_LEN - 2);
601 if (oldCrc != newCrc)
602 {
603 return false;
604 }
605 return true;
606 }
607
GetIDBData(UINT uiIDBCount,PBYTE lpBuf,UINT uiSecCount)608 bool CRKDevice::GetIDBData(UINT uiIDBCount, PBYTE lpBuf, UINT uiSecCount)
609 {
610 PBYTE pIDB;
611 pIDB = new BYTE[uiSecCount * 512];
612 memset(pIDB, 0, uiSecCount * 512);
613 int i, j, iResult;
614 int nSrc = -1, nDst = -1;
615 bool bRet;
616 for (i = 0; i < uiIDBCount; i++)
617 {
618 if (nSrc == -1)
619 {
620 iResult = ReadMutilSector(m_flashInfo.uiSectorPerBlock * m_idBlockOffset[i], uiSecCount, lpBuf);
621 if (iResult != ERR_SUCCESS)
622 {
623 if (m_pLog)
624 {
625 m_pLog->Record(_T("ERROR:GetIDBData-->RKU_ReadSector failed,RetCode(%d)"), iResult);
626 }
627 continue;
628 }
629 nSrc = i;
630 continue;
631 }
632 if (nDst == -1)
633 {
634 iResult = ReadMutilSector(m_flashInfo.uiSectorPerBlock * m_idBlockOffset[i], uiSecCount, pIDB);
635 if (iResult != ERR_SUCCESS)
636 {
637 if (m_pLog)
638 {
639 m_pLog->Record(_T("ERROR:GetIDBData-->RKU_ReadSector failed,RetCode(%d)"), iResult);
640 }
641 continue;
642 }
643 nDst = i;
644 }
645
646 bRet = true;
647
648 for (j = 0; j < uiSecCount; j++)
649 {
650 bRet = memcmp(lpBuf + 512 * j, pIDB + 512 * j, 512) == 0;
651 if (!bRet)
652 {
653 break;
654 }
655 }
656
657 if (bRet)
658 {
659 //��ͬ
660 delete []pIDB;
661 pIDB = NULL;
662 return true;
663 }
664 else
665 {
666 if (m_pLog)
667 {
668 m_pLog->Record(_T("ERROR:GetIDBData-->memcmp failed,src(%d),Dst(%d)"), nSrc, nDst);
669 }
670 memcpy(lpBuf, pIDB, 512 * uiSecCount);
671 nSrc = nDst;
672 nDst = -1;
673 continue;
674 }
675 }
676 delete []pIDB;
677 pIDB = NULL;
678 if (nSrc != -1)
679 {
680 return true;
681 }
682 return false;
683 }
684
GetWriteBackData(UINT uiIDBCount,PBYTE lpBuf)685 bool CRKDevice::GetWriteBackData(UINT uiIDBCount, PBYTE lpBuf)
686 {
687 bool bRet;
688 bRet = GetIDBData(uiIDBCount, lpBuf, 4);
689 return bRet;
690 }
691