Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.80/41: Рейтинг темы: голосов - 41, средняя оценка - 4.80
Вопрощающий

Создание (+распаковка) CAB архива

11.10.2009, 19:26. Показов 10801. Ответов 130

Студворк — интернет-сервис помощи студентам
Обращаясь к cabinet.dll, без использования *.exe
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.10.2009, 19:26
Ответы с готовыми решениями:

Создание архива
Есть такая строка .AddAttachment "C:\logfiles.rar" При выполнении кода на ней ошибка. Как создать программно этот архив?

Программное создание архива.
Добрый день! Можноли программно сделать архив, например, ZIP или rar, не важно и добавить в него файлы? Заранее спасибо.

Создание архива с паролем
Private Declare Sub Sleep Lib "kernel32" (ByVal milliseconds As Long) Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal...

130
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
21.11.2024, 03:09
Студворк — интернет-сервис помощи студентам
testuser2, в TwinBasic будет работать без зависимостей вообще. Что касается той строчки то там это надо для функции DispCallByVtbl плюс ко всему прочему фафалон очень настаивал на том чтобы я так написал.

Добавлено через 2 минуты
testuser2, ты видишь какой сумасшедший код получился) насколько много тут функций) очень долго пришлось работать над этим, пришлось разобрать всё по косточкам буквально, именно для этого модуля я кстати и интересовался темой создания потоков IStream, и как бы мне там ни советовал The Trick подключать TLB тут это не нужно совсем учитывая что мой код работает на лонгах.

Добавлено через 32 секунды
но зато я очень хорошо всё прокомментировал так что любой даже начинающий прогер вполне разберётся там

Добавлено через 23 минуты
Я только ещё пока не разобрался как сделать LZX-сжатие. Там непонятно как-то, такой константы вроде нет.
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
21.11.2024, 16:58
Там есть какой-то макрос, вот он: https://learn.microsoft.com/en... mlzxwindow
Как его написать в VB6? Понятия не имею! Помогите кто знает, пожалуйста?! Там в MSDn же нет исходного кода макроса, как обычно... А как вот написать это на VB?
0
1384 / 839 / 91
Регистрация: 08.02.2017
Сообщений: 3,553
Записей в блоге: 1
21.11.2024, 17:18
Я нашел это в заголовочнике Fci.h, как это перевести на VB х.з. Но в Твин-бейсике появились такие операторы << это, вроде, битовый сдвиг
C++
1
#define TCOMPfromLZXWindow(w)  (((w) << tcompSHIFT_LZX_WINDOW)|(tcompTYPE_LZX))
Добавлено через 2 минуты
"|" в регекспе это значит "или"

Добавлено через 2 минуты
из того же заголовочника
C
1
2
#define tcompSHIFT_LZX_WINDOW  8
#define tcompTYPE_LZX  0x0003
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
21.11.2024, 17:29
И как это всё чудо написать на VB6?
0
1384 / 839 / 91
Регистрация: 08.02.2017
Сообщений: 3,553
Записей в блоге: 1
21.11.2024, 17:52
На Твин Бейсике, я думаю будет так
Visual Basic
1
2
3
Private Sub TCOMPfromLZXWindow(w&)
    w = (w << tcompSHIFT_LZX_WINDOW) Or tcompTYPE_LZX
End Sub
Вот есть функция битового сдвига от GSerg. Используются ассемблерные вставки.

Добавлено через 8 минут
Аналог, того что выше для Твинбейсика, но я не знаю, точно ли это должно быть так
Visual Basic
1
2
3
4
5
6
Private Const tcompSHIFT_LZX_WINDOW = 8
Private Const tcompTYPE_LZX  = 3
'***
Sub TCOMPfromLZXWindow(w As Long)
    w = SHIFT(smShiftLeft, w, tcompSHIFT_LZX_WINDOW) Or tcompTYPE_LZX 'SHIFT - функция GSerg-а
End Sub
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
21.11.2024, 18:48
Так там всё время разные значения вылетают или что? Я чё-то не понял!? Или почему это нельзя сделать константой?

Добавлено через 3 минуты
В описании макроса написано "Макрос TCOMPfromLZXWindow преобразует размер окна в значение LXZTCOMP для FCIAddFile ."
Вопрос: а откуда мы возьмём размер окна? И что такое окно? откуда мне взять значение w чтобы его задать, я что-то вообще не понимаю

Добавлено через 6 минут
Кажись нашёл описание на С++

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
;;  The TCOMPfromLZXWindow macro converts window size into an LXZTCOMP value for FCIAddFile.
;;  Parameters
;;      window_size
;;          The LZX window size. Possible value range is 15-21.
;;
;;  Return value
;;      The return value is a TCOMP value.
;;
;; Syntax
;;    TCOMP TCOMPfromLZXWindow(
;;      INT window_size
;;    );
Добавлено через 1 минуту
Это значит что мне нужно указать "размер окна" (чтобы это ни значило бы) от 15 до 21 это и есть w я думаю

Добавлено через 17 минут
Продолжаем интересные эксперементы, итак написал я на ТвинБейсике:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Private Const tcompSHIFT_LZX_WINDOW = 8
    Private Const tcompTYPE_LZX  = 3
    
    Private Sub TCOMPfromLZXWindow(w&)
        w = (w << tcompSHIFT_LZX_WINDOW) Or tcompTYPE_LZX
    End Sub
 
    Private Sub Command5_Click()
        Dim x As Long
        
        x = 15
        TCOMPfromLZXWindow x
        
        MsgBox x ' 3843
    End Sub
Получилось число 3843 из 15

Добавлено через 44 секунды
Цитата Сообщение от HackerVlad Посмотреть сообщение
<<
К моему удивлению в Твине синтаксический символ << действительно работает.

Добавлено через 3 минуты
testuser2, огромная благодарность тебе тогда за эту функцию на Твине, она помогла!!! Теперь я взял и просто написал 3815 в методе сжатия и вуаля! Ура! Получилось LZX сжатие 15.

Добавлено через 2 минуты
Как я понял, методом тыка, LZX-сжатия бывают от 15 до 21. Где 15 - это сверхбыстрое сжатие и оно как бы разбухает больше, а 21 это самое наилучшая степень сжатия и работает чуть по дольше по времени.

Добавлено через 49 секунд
Остаётся только вопрос почему Microsoft не сделал константы от 15 до 21, поленился?

Добавлено через 29 секунд
Пришлось бы наверное потому что делать 7 констант. А тут один макрос и всё вроде бы как.

Добавлено через 2 минуты
Наилучшая степень сжатия LZX21:

Visual Basic
1
FCIAddFile fci, StrPtr(AnsiSourceFileName), StrPtr(AnsiExtractFileName), 0, AddressOf fnGetNextCabinet, AddressOf fnStatus, AddressOf fnOpenInfo, 5379
Просто пишу 5379 и всё.
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
21.11.2024, 18:53
Теперь я вот наконец-то достиг того о чём так мечтал! Наивысшая степень сжатия! Даже лучше чем RAR сжимает по моему. 3.6 Мб превратилось в 1.9 Мб.
Миниатюры
Создание (+распаковка) CAB архива  
0
1384 / 839 / 91
Регистрация: 08.02.2017
Сообщений: 3,553
Записей в блоге: 1
21.11.2024, 18:56
Рад, что это сработало!
Цитата Сообщение от HackerVlad Посмотреть сообщение
Остаётся только вопрос почему Microsoft не сделал константы от 15 до 21, поленился?
Они сделали только 2 константы в заголовочнике самый низкий и самый высокий уровень
C
1
2
#define tcompLZX_WINDOW_LO  0x0F00
#define tcompLZX_WINDOW_HI  0x1500
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
21.11.2024, 19:01
Странные константы у тебя, я тут посчитал на калькуляторе 0x1500 это 5376 получается, а у меня 5379 выдаёт из 21 наивысшего.

Добавлено через 1 минуту
Я проверил 5376 точно не работает, а вот 5379 точно работает в коде сжатие.

Добавлено через 18 секунд
0x1500 это сколько? неужели я неправильно посчитал
0
1384 / 839 / 91
Регистрация: 08.02.2017
Сообщений: 3,553
Записей в блоге: 1
21.11.2024, 19:03
Цитата Сообщение от HackerVlad Посмотреть сообщение
0x1500 это сколько?
5376 вроде так и есть. Наверное там ошибка
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
21.11.2024, 20:13
testuser2, ну значит 100% там ошибка! потому что 5376 не работает, я это точно проверил уже, а вот 5379 работает!

Добавлено через 2 минуты
Значит твоя константа должна быть 0x1503, а не 0x1500

Добавлено через 18 секунд
Так же и первая твоя константа tcompLZX_WINDOW_LO она тоже неправильная.

Добавлено через 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
#define tcompLZX_WINDOW_LO  0x0F00
#define tcompLZX_WINDOW_HI  0x1500
Значит твои константы должны заканчиваться на тройку

C++
1
2
#define tcompLZX_WINDOW_LO  0x0F03
#define tcompLZX_WINDOW_HI  0x1503
Вот так вот правильно должно быть!

Добавлено через 7 минут
А у них, я нашёл, вот написано вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Global Const $tcompMASK_TYPE          = 0x000F  ;; Mask for compression type
Global Const $tcompTYPE_NONE          = 0x0000  ;; No compression
Global Const $tcompTYPE_MSZIP        = 0x0001  ;; MSZIP
Global Const $tcompTYPE_QUANTUM    = 0x0002  ;; Quantum
Global Const $tcompTYPE_LZX        = 0x0003  ;; LZX
Global Const $tcompBAD              = 0x000F  ;; Unspecified compression type
 
Global Const $tcompMASK_LZX_WINDOW    = 0x1F00  ;; Mask for LZX Compression Memory
Global Const $tcompLZX_WINDOW_LO      = 0x0F00  ;; Lowest LZX Memory (15)
Global Const $tcompLZX_WINDOW_HI      = 0x1500  ;; Highest LZX Memory (21)
Global Const $tcompSHIFT_LZX_WINDOW   = 8      ;; Amount to shift over to get int
 
Global Const $tcompMASK_QUANTUM_LEVEL  = 0x00F0  ;; Mask for Quantum Compression Level
Global Const $tcompQUANTUM_LEVEL_LO    = 0x0010  ;; Lowest Quantum Level (1)
Global Const $tcompQUANTUM_LEVEL_HI    = 0x0070  ;; Highest Quantum Level (7)
Global Const $tcompSHIFT_QUANTUM_LEVEL = 4     ;; Amount to shift over to get int
 
Global Const $tcompMASK_QUANTUM_MEM   = 0x1F00  ;; Mask for Quantum Compression Memory
Global Const $tcompQUANTUM_MEM_LO    = 0x0A00  ;; Lowest Quantum Memory (10)
Global Const $tcompQUANTUM_MEM_HI    = 0x1500  ;; Highest Quantum Memory (21)
Global Const $tcompSHIFT_QUANTUM_MEM  = 8      ;; Amount to shift over to get int
 
Global Const $tcompMASK_RESERVED      = 0xE000  ;; Reserved bits (high 3 bits)
Добавлено через 1 минуту
И хрен тут поймёшь вообще почему они написали 0x0F00 вместо 0x0F03 и почему они написали 0x1500 вместо 0x1503

Добавлено через 59 секунд
И что такое LZX_WINDOW тоже хрен поймёшь вообще

Добавлено через 2 минуты
Кажись допёр! Две константы нужно соединять! То есть делать $tcompTYPE_LZX Or $tcompLZX_WINDOW_HI тогда наверное и получится заветное 0x1503, как ты думаешь?

Добавлено через 6 минут
Да, я только что проверил всё именно так и есть (КАК Я И ДУМАЛ):

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    Private Sub Command5_Click()
        Dim x As Long
        
        Const tcompTYPE_LZX = &H0003& ' 0x0003
        Const tcompLZX_WINDOW_HI = &H1500& ' 0x1500
        
        MsgBox Hex(tcompTYPE_LZX Or tcompLZX_WINDOW_HI) ' HEX: 1503 (это 5379 DEC)
        
        x = 21
        TCOMPfromLZXWindow x
        
        MsgBox x ' 5379
        MsgBox Hex(x) ' 1503
    End Sub
Значит я был неправ. Значит у них нету ошибки. Оказывается константы нужно просто соединять!

Добавлено через 3 минуты
Всегда кстати меня вымораживало почему в синтаксе для приплюсовывания соединения нужно писать Or (или) а не And (и) как казалось бы логически...

Добавлено через 32 минуты
В итоге я такой вот классный енум придумал:

Visual Basic
1
2
3
4
5
6
7
8
9
10
Public Enum cabCompressionMethod
    cm_MSZIP = tcompTYPE_MSZIP
    cm_LZX15 = tcompTYPE_LZX Or tcompLZX_WINDOW_LO
    cm_LZX16 = &H1003&
    cm_LZX17 = &H1103&
    cm_LZX18 = &H1203&
    cm_LZX19 = &H1303&
    cm_LZX20 = &H1403&
    cm_LZX21 = tcompTYPE_LZX Or tcompLZX_WINDOW_HI
End Enum
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
21.11.2024, 21:00
Лучший ответ Сообщение было отмечено HackerVlad как решение

Решение

Новый модуль написал сегодня:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
Option Explicit
'////////////////////////////////////////////
'// Модуль упаковки CAB-архивов            //
'// Copyright (c) 21.11.2024 by HackerVlad //
'// e-mail: vladislavpeshkov@yandex.ru     //
'// Версия 1.2                             //
'////////////////////////////////////////////
 
' Декларации API ...
Private Declare Function FCICreate CDecl Lib "cabinet.dll" (perf As TERF, ByVal fnFilePlaced As Long, ByVal fnAlloc As Long, ByVal fnFree As Long, ByVal fnOpen As Long, ByVal fnRead As Long, ByVal fnWrite As Long, ByVal fnClose As Long, ByVal fnSeek As Long, ByVal fnDelete As Long, ByVal fnFciGTF As Long, ByVal ccab As Long, Optional ByVal pv As Long) As Long
Private Declare Function FCIAddFile CDecl Lib "cabinet.dll" (ByVal hfci As Long, ByVal pszSourceFile As Long, ByVal pszFileName As Long, ByVal fExecute As BOOL, ByVal pfnGetNextCabinet As Long, ByVal pfnProgress As Long, ByVal pfnOpenInfo As Long, ByVal typeCompress As Long) As Long
Private Declare Function FCIFlushCabinet CDecl Lib "cabinet.dll" (ByVal hfci As Long, ByVal fGetNextCab As BOOL, ByVal pfnfcignc As Long, ByVal pfnfcis As Long) As BOOL
Private Declare Function FCIDestroy CDecl Lib "cabinet.dll" (ByVal hfci As Long) As BOOL
Private Declare Function SHCreateMemStream Lib "shlwapi.dll" Alias "#12" (ByVal pInit As Long, ByVal cbInit As Long) As Long
Private Declare Function PathStripPathW Lib "shlwapi.dll" (ByVal pszPath As Long) As Long
Private Declare Function PathRemoveFileSpecW Lib "shlwapi.dll" (ByVal pszPath As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" (ByVal lpFileName As Long) As Long
Private Declare Function GetFileTime Lib "kernel32" (ByVal hFile As Long, lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As FILETIME) As Long
Private Declare Function FileTimeToLocalFileTime Lib "kernel32" (lpFileTime As FILETIME, lpLocalFileTime As FILETIME) As Long
Private Declare Function FileTimeToDosDateTime Lib "kernel32" (lpFileTime As FILETIME, lpFatDate As Integer, lpFatTime As Integer) As Long
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Any) As BOOL
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Any) As BOOL
Private Declare Function OpenFile Lib "kernel32" (ByVal lpFileName As Long, lpReOpenBuff As OFSTRUCT, ByVal wStyle As Long) As Long
Private Declare Function CreateFileA Lib "kernel32" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CreateFileW Lib "kernel32" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function GetMem4 Lib "msvbvm60" (ByVal Addr As Long, ByRef dstValue As Long) As Long
 
' Константы ...
Private Const CB_MAX_DISK_NAME = 256
Private Const CB_MAX_CABINET_NAME = 256
Private Const CB_MAX_CAB_PATH = 256
Private Const OFS_MAXPATHNAME = 128
Private Const GENERIC_READ As Long = &H80000000
Private Const GENERIC_WRITE As Long = &H40000000
Private Const FILE_SHARE_READ = &H1
Private Const OPEN_EXISTING As Long = 3
Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Const CREATE_ALWAYS = 2
Private Const MAX_PATH As Long = 260
Private Const tcompTYPE_MSZIP = &H1&
Private Const tcompTYPE_LZX = &H3& ' 0x0003
Private Const tcompLZX_WINDOW_LO = &HF00& ' 0x0F00
Private Const tcompLZX_WINDOW_HI = &H1500& ' 0x1500
 
' Типы ...
Private Type TCCAB
    cb As Long ' size available for cabinet on this media
    cbFolderThresh As Long ' Thresshold for forcing a new Folder
    cbReserveCFHeader As Long ' Space to reserve in CFHEADER
    cbReserveCFFolder As Long ' Space to reserve in CFFOLDER
    cbReserveCFData As Long ' Space to reserve in CFDATA
    iCab As Long ' sequential numbers for cabinets
    iDisk As Long ' Disk number
    fFailOnIncompressible As Long ' TRUE => Fail if a block is incompressible
    setID As Integer ' Cabinet set ID
    szDisk(0 To (CB_MAX_DISK_NAME - 1)) As Byte ' current disk name
    szCab(0 To (CB_MAX_CABINET_NAME - 1)) As Byte ' current cabinet name
    szCabPath(0 To (CB_MAX_CAB_PATH - 1)) As Byte ' path for creating cabinet
End Type
 
Private Type TERF
    erfOper As Long
    erfType As Long
    fError As Byte
End Type
 
Private Type OFSTRUCT
    cBytes As Byte
    fFixedDisk As Byte
    nErrCode As Integer
    Reserved1 As Integer
    Reserved2 As Integer
    szPathName(0 To (OFS_MAXPATHNAME - 1)) As Byte
End Type
 
Private Type FILETIME
  dwLowDateTime As Long
  dwHighDateTime As Long
End Type
 
' Переменные для временного хранения данных ...
Dim fh As Long
Dim fh_cab As Long
Dim cabFileName As String
 
' Енумы ...
Private Enum BOOL
    cFalse
    cTrue
End Enum
 
Private Enum Stream_Seek
    STREAM_SEEK_SET
    STREAM_SEEK_CUR
    STREAM_SEEK_END
End Enum
 
Public Enum cabCompressionMethod
    cm_MSZIP = tcompTYPE_MSZIP
    cm_LZX15 = tcompTYPE_LZX Or tcompLZX_WINDOW_LO
    cm_LZX16 = &H1003&
    cm_LZX17 = &H1103&
    cm_LZX18 = &H1203&
    cm_LZX19 = &H1303&
    cm_LZX20 = &H1403&
    cm_LZX21 = tcompTYPE_LZX Or tcompLZX_WINDOW_HI
End Enum
 
' Для совместимости с TwinBasic и VBA7
#If (VBA7 <> 0) Or (TWINBASIC <> 0) Then
    Private Declare PtrSafe Function DispCallFunc Lib "oleaut32" (ByVal pvInstance As LongPtr, ByVal oVft As LongPtr, ByVal lCc As Long, ByVal vtReturn As VbVarType, ByVal cActuals As Long, prgVt As Any, prgpVarg As Any, pvargResult As Variant) As Long
#Else
    Private Declare Function DispCallFunc Lib "oleaut32" (ByVal pvInstance As LongPtr, ByVal oVft As LongPtr, ByVal lCc As Long, ByVal vtReturn As VbVarType, ByVal cActuals As Long, prgVt As Any, prgpVarg As Any, pvargResult As Variant) As Long
    
    Private Enum LongPtr
        [_]
    End Enum
#End If
 
Private Function DispCallByVtbl(ByVal pUnk As LongPtr, ByVal lIndex As Long, ParamArray A() As Variant) As Variant
    Const CC_STDCALL    As Long = 4
#If Win64 Then
    Const PTR_SIZE      As Long = 8
#Else
    Const PTR_SIZE      As Long = 4
#End If
    Dim lIdx            As Long
    Dim vParam()        As Variant
    Dim vType(0 To 63)  As Integer
    Dim vPtr(0 To 63)   As LongPtr
    Dim hResult         As Long
    
    vParam = A
    For lIdx = 0 To UBound(vParam)
        vType(lIdx) = VarType(vParam(lIdx))
        vPtr(lIdx) = VarPtr(vParam(lIdx))
    Next
    hResult = DispCallFunc(pUnk, lIndex * PTR_SIZE, CC_STDCALL, vbLong, lIdx, vType(0), vPtr(0), DispCallByVtbl)
    If hResult < 0 Then
        Err.Raise hResult, "DispCallFunc"
    End If
End Function
 
Private Function IStream_Read(ByVal ptrIStream As Long, ByVal pv As Long, ByVal BytesRead As Long) As Long
    Dim BytesReaded As Long
    
    DispCallByVtbl ptrIStream, 3, pv, BytesRead, VarPtr(BytesReaded)
    IStream_Read = BytesReaded
End Function
 
Private Function IStream_Write(ByVal ptrIStream As Long, ByVal pv As Long, ByVal BytesWrite As Long) As Long
    Dim BytesWritten As Long
    
    DispCallByVtbl ptrIStream, 4, pv, BytesWrite, VarPtr(BytesWritten)
    IStream_Write = BytesWritten
End Function
 
Private Function IStream_Seek(ByVal ptrIStream As Long, ByVal Offset As Currency, ByVal Origin As Stream_Seek) As Long
    Dim NewPosition As Currency
    
    DispCallByVtbl ptrIStream, 5, Offset, Origin, VarPtr(NewPosition)
    IStream_Seek = NewPosition * 10000@
End Function
 
Private Sub IStream_Release(ByVal ptrIStream As Long)
    DispCallByVtbl ptrIStream, 2
End Sub
 
' +++ FCICreate CallBack's +++
 
' 1. Выделение памяти
' Описание макроса: https://learn.microsoft.com/en-us/windows/win32/api/fdi/nf-fdi-fnalloc
' Delphi: function fnAlloc(Size: ULONG): Pointer; cdecl;
Private Function fnAlloc CDecl(ByVal lngSize As Long) As Long
    fnAlloc = GlobalAlloc(0, lngSize)
End Function
 
' 2. Создание временного файла (потока)
' Delphi: function fnFciGTF(pszTempName: PAnsiChar; cbTempName: Integer; pv: Pointer): BOOL; cdecl;
Private Function fnFciGTF CDecl(ByRef pszTempName As Long, ByVal cbTempName As Long, ByVal pv As Long) As BOOL
    ' Специальный хак:
    ' Обманываем операционную систему, которая будет "думать", что работает с TMP-файлами на диске
    ' Вместо временного файла на диске, мы будем создавать поток IStream в оперативной памяти своего процесса
    Dim hStream As Long
    
    hStream = SHCreateMemStream(0, 0) ' Создать новый поток IStream для временного файла
    pszTempName = hStream ' Здесь мы будем использовать хак: засовываем в переменную String значение Long
    fnFciGTF = 1
End Function
 
' 3. Открытие файла (потока)
' Описание макроса: https://learn.microsoft.com/en-us/windows/win32/api/fdi/nf-fdi-fnopen
' Delphi: function fnOpen(pszFile: PAnsiChar; oflag: Integer; pmode: Integer; err: PInteger; pv: Pointer): Integer; cdecl;
Private Function fnOpen CDecl(ByRef pszFile As Long, ByVal oFlag As Long, ByVal pMode As Long, ByRef ErrNo As Long, ByVal pv As Long) As Long
    If oFlag <> &H8302& Then ' Хак
        fnOpen = pszFile
    Else
        fh_cab = CreateFileW(StrPtr(cabFileName), GENERIC_WRITE, FILE_SHARE_READ, ByVal 0&, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0)
        
        If fh_cab <> INVALID_HANDLE_VALUE Then
            ErrNo = Err.LastDllError
            fnOpen = fh_cab
        Else
            ErrNo = Err.LastDllError
            fnOpen = -1
        End If
    End If
End Function
 
' 4. Чтение данных
' Описание макроса: https://learn.microsoft.com/en-us/windows/win32/api/fdi/nf-fdi-fnread
' Delphi: function fnRead(hf: Integer; memory: Pointer; cb: UINT; err: PInteger; pv: Pointer): UINT; cdecl;
Private Function fnRead CDecl(ByVal hf As Long, ByVal hMemory As Long, ByVal cbSize As Long, ByRef ErrNo As Long, ByVal pv As Long) As Long
    Dim dwBytesRead As Long
    
    If hf = fh Then ' Если открывается на чтение файл, который добавляется в архив
        If ReadFile(fh, hMemory, cbSize, dwBytesRead, ByVal 0&) = cFalse Then
            ErrNo = Err.LastDllError
            fnRead = -1
            Exit Function
        End If
    Else ' Если открывается на чтение временный поток IStream
        dwBytesRead = IStream_Read(hf, hMemory, cbSize)
    End If
    
    fnRead = dwBytesRead
End Function
 
' 5. Запись данных
' Описание макроса: https://learn.microsoft.com/en-us/windows/win32/api/fdi/nf-fdi-fnwrite
' Delphi: function fnWrite(hf: Integer; memory: Pointer; cb: UINT; err: PInteger; pv: Pointer): UINT; cdecl;
Private Function fnWrite CDecl(ByVal hf As Long, ByVal hMemory As Long, ByVal cbSize As Long, ByRef ErrNo As Long, ByVal pv As Long) As Long
    Dim dwBytesWritten As Long
    
    If hf = fh_cab Then ' Если открывается на запись файл архива
        If WriteFile(fh_cab, hMemory, cbSize, dwBytesWritten, ByVal 0&) = cFalse Then
            ErrNo = Err.LastDllError
            fnWrite = -1
            Exit Function
        End If
    Else ' Если открывается на запись временный поток IStream
        dwBytesWritten = IStream_Write(hf, hMemory, cbSize)
    End If
    
    fnWrite = dwBytesWritten
End Function
 
' 6. Освобождение памяти
' Описание макроса: https://learn.microsoft.com/en-us/windows/win32/api/fdi/nf-fdi-fnfree
' Delphi: procedure fnFree(memory: Pointer); cdecl;
Private Sub fnFree CDecl(ByVal lngMemory As Long)
    GlobalFree lngMemory
End Sub
 
' 7. Позиционирование указателя
' Описание макроса: https://learn.microsoft.com/en-us/windows/win32/api/fdi/nf-fdi-fnseek
' Delphi: function fnSeek(hf: Integer; dist: Longint; seektype: Integer; err: PInteger; pv: Pointer): Longint; cdecl;
Private Function fnSeek CDecl(ByVal hf As Long, ByVal dist As Long, ByVal seektype As Long, ByRef ErrNo As Long, pv As Long) As Long
    Dim newPos As Long
    
    If hf = fh Or hf = fh_cab Then ' Если открывается на позиционирование файл, который добавляется в архив, либо сам файл архива
        newPos = SetFilePointer(hf, dist, ByVal 0&, seektype)
        ErrNo = Err.LastDllError
    Else ' Позиционирование "временного файла" то есть потока
        newPos = IStream_Seek(hf, dist / 10000@, seektype)
    End If
    
    fnSeek = newPos
End Function
 
' 8. Закрытие файла (потока)
' Описание макроса: https://learn.microsoft.com/en-us/windows/win32/api/fdi/nf-fdi-fnclose
' Delphi: function fnClose(hf: Integer; err, pv: Pointer): Integer; cdecl;
Private Function fnClose CDecl(ByVal hf As Long, ErrNo As Long, pv As Long) As Long
    If hf = fh Or hf = fh_cab Then ' Если закрывать нужно файл, который добавляется в архив, либо нужно закрывать сам файл архива
        CloseHandle hf
    End If
    
    fnClose = 0
End Function
 
' 9. Удаление временного файла (потока)
' Delphi: function fnDelete(pszFile: PAnsiChar; err: PInteger; pv: Pointer): Integer; cdecl;
Private Function fnDelete CDecl(ByRef pszFile As Long, ErrNo As Long, pv As Long) As Long
    IStream_Release pszFile
    fnDelete = 0
End Function
 
' 10. Вызывается каждый раз при добавлении нового файла в архив
' Delphi: function fnFilePlaced(var ccab: TCCAB; pszFile: PAnsiChar; cbFile: Longint; fContinuation: BOOL; pv: Pointer): THandle; cdecl;
Private Function fnFilePlaced CDecl(ccab As TCCAB, ByVal pszFile As String, ByVal FileSize As Long, ByVal fContinuation As BOOL, ByVal pv As Long) As Long
    ' Здесь можно получить полезные данные:
    ' 1. FileSize
    ' 2. StrConv(ccab.szCabPath, vbUnicode)
    ' 3. StrConv(ccab.szCab, vbUnicode)
    
    fnFilePlaced = 0
End Function
 
' --- FCICreate CallBack's ---
 
' +++ FCIAddFile CallBack's +++
 
' 11. Устанавливаем атрибуты файла
' Delphi: function fnOpenInfo(pszName: PAnsiChar; var pDate: WORD; var pTime: WORD; var pAttrib: WORD; err: PInteger; pv: Pointer): Integer; cdecl;
' Syntax C++
' ;;    void FNFCIGETOPENINFO(
' ;;      [in]  LPSTR pszName,
' ;;      USHORT *pdate,
' ;;      USHORT *ptime,
' ;;      USHORT *pattribs,
' ;;      int FAR *err,
' ;;      void FAR *pv
' ;;    );
Private Function fnOpenInfo CDecl(ByVal pszName As String, pDate As Integer, pTime As Integer, pAttribs As Integer, ErrNo As Long, ByVal pv As Long) As Long
    Dim LocalTime As FILETIME
    Dim CreationTime As FILETIME
    Dim LastAccessTime As FILETIME
    Dim LastWriteTime As FILETIME
    
    pAttribs = GetFileAttributes(StrPtr(pszName))
    fh = CreateFileA(StrPtr(pszName), GENERIC_READ, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
    
    If fh <> INVALID_HANDLE_VALUE Then
        GetFileTime fh, CreationTime, LastAccessTime, LastWriteTime
        FileTimeToLocalFileTime LastWriteTime, LocalTime
        FileTimeToDosDateTime LocalTime, pDate, pTime
        
        fnOpenInfo = fh
    Else
        ErrNo = Err.LastDllError
        fnOpenInfo = -1
    End If
End Function
 
' 12. Вызывается на нескольких этапах обработки файла: сжатие блока, добавление сжатого блока и запись архива
' Delphi: function fnStatus(typeStatus: UINT; cb1, cb2: ULONG; pv: Pointer): Longint; cdecl;
Private Function fnStatus CDecl(ByVal typeStatus As Long, ByVal cb1 As Long, ByVal cb2 As Long, ByVal pv As Long) As Long
    fnStatus = 0
End Function
 
' 13. Вызывается перед созданием нового тома архива
' Delphi: function fnGetNextCabinet(var ccab: TCCAB; cbPrevCab: ULONG; pv: Pointer): BOOL; cdecl;
Private Function fnGetNextCabinet CDecl(ccab As TCCAB, ByVal cbPrevCab As Long, ByVal pv As Long) As BOOL
    fnGetNextCabinet = 0
End Function
 
' --- FCIAddFile CallBack's ---
 
' Упаковать файлы в архив CAB
' Функция принимает в качестве параметров SourceFullFileNames, DestFileNames строку (если файл один) либо массив строк (список файлов)
' DestFileNames - это необязательный параметр, это путь и имя файла внутри архива CAB
Public Function CabinetAddFiles(ByVal CabinetFullFileName As String, SourceFullFileNames As Variant, Optional DestFileNames As Variant, Optional CompressionMethod As cabCompressionMethod = cm_LZX21) As Boolean
    Dim ccab As TCCAB
    Dim erf As TERF
    Dim fci As Long
    Dim CabinetDisk As String
    Dim CabinetName As String
    Dim CabinetPath As String
    Dim AnsiSourceFileName As String
    Dim AnsiExtractFileName As String
    Dim AnsiDestinationFileName As String
    Dim AnsiSourceFullFileNames() As String
    Dim AnsiDestFileNames() As String
    Dim DestFileNamesArrayInitialized As Boolean
    Dim i As Long
    
    If Len(CabinetFullFileName) = 0 Then Exit Function
    
    If IsArray(SourceFullFileNames) Then ' Если это массив
        If CabinetIsArrayInitialized(SourceFullFileNames) = True Then ' Если массив инициализирован
            For i = 0 To UBound(SourceFullFileNames)
                AnsiSourceFileName = StrConv(SourceFullFileNames(i), vbFromUnicode) ' Преобразовать в ANSI
                
                If InStrB(1, AnsiSourceFileName, ChrB(&H3F)) > 0 Then
                    ' Cabinet.dll не поддерживает юникодные имена файлов для упаковки
                    Exit Function
                End If
                
                ' Копируем массив, только в результатирующем массиве будут имена файлов в кодировке ANSI
                CabinetInsertArrayString AnsiSourceFullFileNames, AnsiSourceFileName
            Next
        Else
            Exit Function
        End If
    Else
        If VarType(SourceFullFileNames) = vbString Then
            If SourceFullFileNames <> vbNullString Then
                AnsiSourceFileName = StrConv(SourceFullFileNames, vbFromUnicode) ' Преобразовать в ANSI
                
                If InStrB(1, AnsiSourceFileName, ChrB(&H3F)) > 0 Then
                    ' Cabinet.dll не поддерживает юникодные имена файлов для упаковки
                    Exit Function
                End If
                
                CabinetInsertArrayString AnsiSourceFullFileNames, AnsiSourceFileName ' В массиве будет только одна строка
            Else ' Строка не должна быть пустой
                Exit Function
            End If
        Else ' Ошибка типа данных (не массив и не строка)
            Exit Function
        End If
    End If
    
    If IsArray(DestFileNames) Then
        If CabinetIsArrayInitialized(SourceFullFileNames) = True Then ' Если массив инициализирован
            If UBound(SourceFullFileNames) <> UBound(DestFileNames) Then Exit Function ' Не совпадают границы массивов
            
            For i = 0 To UBound(DestFileNames)
                AnsiDestinationFileName = StrConv(DestFileNames(i), vbFromUnicode) ' Преобразовать в ANSI
                
                If InStrB(1, AnsiDestinationFileName, ChrB(&H3F)) > 0 Then
                    ' Cabinet.dll не поддерживает юникодные имена файлов для упаковки
                    Exit Function
                End If
                
                ' Копируем массив, только в результатирующем массиве будут имена файлов в кодировке ANSI
                CabinetInsertArrayString AnsiDestFileNames, AnsiDestinationFileName
            Next
            
            DestFileNamesArrayInitialized = True
        End If
    Else
        If VarType(DestFileNames) = vbString Then
            If DestFileNames <> vbNullString Then
                AnsiDestinationFileName = StrConv(DestFileNames, vbFromUnicode) ' Преобразовать в ANSI
                
                If InStrB(1, AnsiDestinationFileName, ChrB(&H3F)) > 0 Then
                    ' Cabinet.dll не поддерживает юникодные имена файлов для упаковки
                    Exit Function
                End If
                
                CabinetInsertArrayString AnsiDestFileNames, AnsiDestinationFileName ' В массиве будет только одна строка
                DestFileNamesArrayInitialized = True
            End If
        End If
    End If
    
    ' Прежде всего нужно взять FullFileName будущего архива и извлечь из него путь к папке и имя файла
    CabinetName = StrConv(CabinetExtractFileName(CabinetFullFileName), vbFromUnicode) ' Преобразовать в ANSI
    CabinetPath = StrConv(CabinetExtractFilePath(CabinetFullFileName), vbFromUnicode) ' Преобразовать в ANSI
    
    ' Определить значения структуры
    ccab.cb = &H7FFFFFFF  ' The maximum size, in bytes, of a cabinet created by FCI
    ccab.iDisk = 1
    
    CabinetDisk = StrConv("DISK1", vbFromUnicode) ' Я не знаю почему, но надо писать "DISK1"
    CopyMemory VarPtr(ccab.setID) + 2, StrPtr(CabinetDisk), LenB(CabinetDisk) ' ccab.szDisk = CabinetDisk
    CopyMemory VarPtr(ccab.setID) + 2 + 256, StrPtr(CabinetName), LenB(CabinetName) ' ccab.szCab = CabinetName
    CopyMemory VarPtr(ccab.setID) + 2 + 512, StrPtr(CabinetPath), LenB(CabinetPath) ' ccab.szCabPath = CabinetPath
    cabFileName = CabinetFullFileName ' Запомнить FileName будущего архива
    
    fci = FCICreate(erf, AddressOf fnFilePlaced, AddressOf fnAlloc, AddressOf fnFree, AddressOf fnOpen, AddressOf fnRead, AddressOf fnWrite, AddressOf fnClose, AddressOf fnSeek, AddressOf fnDelete, AddressOf fnFciGTF, VarPtr(ccab))
    
    If fci <> 0 Then
        For i = 0 To UBound(AnsiSourceFullFileNames)
            AnsiSourceFileName = AnsiSourceFullFileNames(i)
            If DestFileNamesArrayInitialized = True Then
                AnsiExtractFileName = AnsiDestFileNames(i)
            Else
                If IsArray(SourceFullFileNames) Then ' Если это массив
                    AnsiExtractFileName = StrConv(CabinetExtractFileName(SourceFullFileNames(i)), vbFromUnicode) ' Преобразовать в ANSI
                Else
                    AnsiExtractFileName = StrConv(CabinetExtractFileName(SourceFullFileNames), vbFromUnicode) ' Преобразовать в ANSI
                End If
            End If
            
            FCIAddFile fci, StrPtr(AnsiSourceFileName), StrPtr(AnsiExtractFileName), 0, AddressOf fnGetNextCabinet, AddressOf fnStatus, AddressOf fnOpenInfo, CompressionMethod
        Next
        
        If FCIFlushCabinet(fci, cFalse, AddressOf fnGetNextCabinet, AddressOf fnStatus) = cTrue Then
            CabinetAddFiles = True
        End If
        
        FCIDestroy fci
    End If
    
    cabFileName = vbNullString
End Function
 
' Преобразовать полный путь кабинета в имя файла
Public Function CabinetExtractFileName(ByVal FileName As String) As String
    Dim lNullPos As Long
    Dim pszPath As String
    
    pszPath = FileName
    PathStripPathW StrPtr(pszPath)
    
    lNullPos = InStr(1, pszPath, vbNullChar)
    If lNullPos Then
        CabinetExtractFileName = Left$(pszPath, lNullPos - 1)
    Else
        CabinetExtractFileName = FileName
    End If
End Function
 
' Преобразовать полный путь кабинета в путь к папке (всегда возвращает на конце "\")
Public Function CabinetExtractFilePath(ByVal FileName As String) As String
    Dim lNullPos As Long
    Dim pszPath As String
    
    pszPath = FileName
    PathRemoveFileSpecW StrPtr(pszPath)
    
    lNullPos = InStr(1, pszPath, vbNullChar)
    If lNullPos Then
        pszPath = Left$(pszPath, lNullPos - 1)
        If Right$(pszPath, 1) <> "\" Then pszPath = pszPath & "\"
        CabinetExtractFilePath = pszPath
    Else
        CabinetExtractFilePath = FileName
    End If
End Function
 
' Добавить строку в массив, в не зависимости от того, был ли он инициализирован
Public Sub CabinetInsertArrayString(ByRef strArr() As String, ByVal InsertString As String)
    Dim NewIndex As Long
    
    If CabinetIsArrayInitialized(strArr) = False Then
        ReDim strArr(0)
        strArr(0) = InsertString
    Else
        NewIndex = UBound(strArr) + 1
        
        ReDim Preserve strArr(NewIndex)
        strArr(NewIndex) = InsertString
    End If
End Sub
 
' Инициализирован ли массив
Public Function CabinetIsArrayInitialized(arr) As Boolean
    Dim saAddress As Long
    
    GetMem4 VarPtr(arr) + 8, saAddress
    GetMem4 saAddress, saAddress
    CabinetIsArrayInitialized = (saAddress <> 0)
    If CabinetIsArrayInitialized Then CabinetIsArrayInitialized = UBound(arr) >= LBound(arr)
End Function
Миниатюры
Создание (+распаковка) CAB архива  
1
1384 / 839 / 91
Регистрация: 08.02.2017
Сообщений: 3,553
Записей в блоге: 1
22.11.2024, 01:53
А чего quantum не добавил?
Цитата Сообщение от HackerVlad Посмотреть сообщение
Global Const $tcompQUANTUM_LEVEL_LO = 0x0010 ;; Lowest Quantum Level (1)
Global Const $tcompQUANTUM_LEVEL_HI = 0x0070 ;; Highest Quantum Level (7)
Там тоже есть разные уровни компрессии..
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
22.11.2024, 01:59
testuser2, да, но я не пробовал эти квантумы...

Добавлено через 1 минуту
жмёт мне кажется хуже чем LZX
0
1384 / 839 / 91
Регистрация: 08.02.2017
Сообщений: 3,553
Записей в блоге: 1
22.11.2024, 02:01
Просто название, как бы многообещающее, может это супербыстрый алгоритм?
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
22.11.2024, 02:01
если хочешь сам попробуй
0
1384 / 839 / 91
Регистрация: 08.02.2017
Сообщений: 3,553
Записей в блоге: 1
22.11.2024, 02:02
Толком ни чего не могу про него найти кроме
Существует три алгоритма сжатия, используемых в CAB-файлах, включая «Deflate» Филом Кацем (который такой же, как и в ZIP-файлах), «Quantum» Дэвида Стаффорда и «LZX» Джонатаном Форбсом и Томи Поутаненом.
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
22.11.2024, 02:04
Ну и какой их них самый лучший?
0
1384 / 839 / 91
Регистрация: 08.02.2017
Сообщений: 3,553
Записей в блоге: 1
22.11.2024, 02:12
Вот сравнение MSZIP и LZX
MSZIP сжимает каждый файл один за другим, а затем сохраняет сжатые данные в CAB-файле.
LZX работает совершенно по-другому: сначала он создает дерево Хаффмана из всех файлов, а затем сохраняет все дерево в файле CAB.
Последствия заметны при многократном сжатии одного и того же файла:
сжатие 3 идентичных (или почти идентичных) файлов с помощью MSZIP приводит к увеличению размера CAB на 300% по сравнению со сжатием одного файла.
Сжатие 3 идентичных (или почти идентичных) файлов с помощью LZX приводит к увеличению размера CAB примерно на 110%.
Про квантум даже Википедия молчит
Миниатюры
Создание (+распаковка) CAB архива  
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
22.11.2024, 02:20
testuser2, ну хорошо, ты попробуй свой квантум, потом скажешь как он жмёт лучше или нет

Добавлено через 1 минуту
testuser2, тебе для твоего VBA7 правда придётся переписывать все API

Добавлено через 46 секунд
хотя в VBA7 точно фурычить не будет там же навреное не будет работать надстройка CDeckFix хотя я не пробовал
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.11.2024, 02:20
Помогаю со студенческими работами здесь

Создание установочного архива для своих любимых программ
Многие новички в программировании рано или поздно создают программы или игры, которыми хотят поделиться с другими пользователями или своими...

Распаковка архива rar без сохранения файла во временную папку
В архиве rar хранится сжатый (с паролем) файл txt, как его распаковать (пароль известен) чтобы файл не записывался на диск, а содержимому...

Создание архива с паролем средствами PB. Возможно?
Есть ли какая то библиотека что позволяет запихнуть PB кодом файлы в архив с паролем? Ну и соответственно извлекать из архива. Спасибо.

Создание cab архива
Здравствуйте! Помогите реализовать код создания cab архива с помощью CabinetAPI Код из msdn не получается скомпилировать, не понимаю...

Создание папки с датой в имени и распаковка в неё архива
Есть папка на диске С:\Arhiv в нем есть архивы по датам! надо что бы брал самый последний архив по дате и распаковывал в корень С:\Arhiv\...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru