Занести в таблицу смещения меток. На FASM

Тема в разделе "WASM.BEGINNERS", создана пользователем Adrax, 2 июл 2007.

  1. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    Уважаемые программисты! Прошу вашей помощи:
    есть таблица указателей на обработчики сообщений:
    Код (Text):
    1. menu_handlers
    2. dd offset h_idm_new
    3. dd offset h_idm_open
    4. dd offset h_idm_save
    5. dd offset h_idm_saveas
    6. dd offset h_idm_exit
    7. dd offset h_idm_about
    В eax - ID пункта меню, переход на нужный обработчик совершается так:
    Код (Text):
    1. call dword ptr menu_handlers[eax*4]
    Это из MASM'овского кода...
    Вопрос: как такое провернуть на FASM? Директивы offset там нет, а если я просто создаю таблицу с именами меток, присутствующих в коде - вызов, вроде идёт, но не по тому адресу, где расположен обработчик. Как мне занести в таблицу смещения меток?
    Вызов я делаю так: call dword [menu_handlers+eax*4] - правильно ли?
    Заранее благодарен
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    набросайте пример как делаете в фасме
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Код (Text):
    1. table:
    2.     dd address1, address2, address3
    3. ...
    4. call dword [table + eax * 4]
     
  4. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 rei3er
    Я так и делаю, но прога при нажатии на любой пункт меню выдаёт access violation, отсюда я делаю вывод, что вызов идёт не по тем адресам...
    Выложу весь свой исходник на FASM, но он здоровенный жутко:dntknw:
    Код (Text):
    1. format PE GUI 4.0
    2. include 'win32axp.inc'
    3. include 'encoding\WIN1251.INC'
    4. ID_MENU = 700h
    5. ID_ACCEL = 701h
    6. ID_ABOUT = 702h
    7. EM_GETTEXTLENGTHEX = WM_USER+95
    8. EditID = 1
    9.  
    10. .data
    11.  
    12.   name db 'RFpad',0
    13.   editK db 'edit',0
    14.   changes db 'Do you want to save changes?',0
    15.   filter  db  "All Files",0,'*.*',0
    16.           db  "Text Files",0, '*.txt',0,0
    17.  
    18.  
    19.   wc WNDCLASS 0,Procedura,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,ID_MENU,name
    20.  
    21.   ofn OPENFILENAME 28h,0,0,filter,0,0,0,buffer,260,0,0,0,0,0,0,0,0,0,0,0
    22.  buffer rb 260
    23.   newflag db 1
    24.   edith dd ?
    25.   pmem dd ?
    26.   accelh dd ?
    27.   sizeRW dd ?
    28.   hmem dd ?
    29.   filesize dd ?
    30.   client RECT
    31.   msg MSG
    32.  
    33. table dd NEW
    34.       dd OPEN
    35.       dd SAVE
    36.       dd SAVEAS
    37.       dd EXIT
    38.       dd ABOUT
    39.       dd UNDO
    40.       dd CUT
    41.       dd COPY
    42.       dd PASTE
    43.       dd CLEAR
    44.       dd SETSEL
    45.  
    46. .code
    47.  
    48.   fuck:
    49.         invoke GetCommandLine
    50.         mov edi,eax
    51.         mov al,20h
    52.         mov ecx,260
    53.         repne scasb
    54.         cmp byte [edi],0
    55.         je cmdline_empty
    56.         mov esi,edi
    57.         mov edi,buffer
    58.         rep movsb
    59.         mov [newflag],0
    60. cmdline_empty:
    61.         invoke  GetModuleHandle,0
    62.         mov     [wc.hInstance],eax
    63.         invoke  LoadIcon,0,IDI_APPLICATION
    64.         mov     [wc.hIcon],eax
    65.         invoke  LoadCursor,0,IDC_ARROW
    66.         mov     [wc.hCursor],eax
    67.         invoke  RegisterClass,wc
    68.         invoke  CreateWindowEx,0,name,name,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,192,192,NULL,NULL,[wc.hInstance],NULL
    69.         invoke LoadAccelerators,[wc.hInstance],ID_ACCEL
    70.         mov [accelh],eax
    71.  
    72.  
    73.   msg_loop:
    74.         invoke  GetMessage,msg,NULL,0,0
    75.         or      eax,eax
    76.         jz      end_loop
    77.  
    78.         invoke TranslateAccelerator,[wc.hInstance],[accelh],msg
    79.         test eax,eax
    80.         jnz msg_loop
    81.  
    82.         invoke  TranslateMessage,msg
    83.         invoke  DispatchMessage,msg
    84.         jmp     msg_loop
    85.   end_loop:
    86.         invoke  ExitProcess,[msg.wParam]
    87.  
    88.  
    89.  
    90. proc Procedura hwnd,wmsg,wparam,lparam
    91.         push ebx
    92.         push esi
    93.         push edi
    94.         cmp [wmsg],WM_COMMAND
    95.         je Command
    96.         cmp [wmsg],WM_SIZE
    97.         je Siz
    98.         cmp [wmsg],WM_ACTIVATE
    99.         je Act
    100.         cmp [wmsg],WM_CLOSE
    101.         je Close
    102.         cmp [wmsg],WM_CREATE
    103.         je Create
    104.         cmp [wmsg],WM_DESTROY
    105.         je Destroy
    106.      xx:
    107.         invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
    108.         jmp finish
    109.  
    110.   Close:
    111.         call [saving]
    112.         jmp xx
    113.  
    114.   Create:
    115.         invoke GetClientRect,[hwnd],client
    116.         invoke CreateWindowEx,WS_EX_CLIENTEDGE,editK,0,WS_VISIBLE+WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,[client.left],[client.top],[client.right],[client.bottom],[hwnd],0,[wc.hInstance],NULL
    117.         test eax,eax
    118.         jz fail
    119.         mov [edith],eax
    120.         invoke SetFocus,eax
    121.         cmp [newflag],1
    122.         je continue
    123.         call getopen
    124.   continue:
    125.         xor eax,eax
    126.         jmp finish
    127.   fail:
    128.         or eax,-1
    129.         jmp finish
    130.  
    131.  
    132.  Command:
    133.         mov eax,[wparam]      
    134.         cmp ax,100h
    135.         jb continue        
    136.         call dword [table+eax*4]
    137.         jmp continue
    138.  
    139.  SETSEL:
    140.         invoke SendMessage,[edith],EM_SETSEL,0,-1
    141.         ret
    142.  
    143.  CLEAR:
    144.        mov eax,WM_CLEAR
    145.        jmp sendt
    146.  PASTE:
    147.         mov eax,WM_PASTE
    148.         jmp sendt
    149.  COPY:
    150.         mov eax,WM_COPY
    151.         jmp sendt
    152.  CUT:
    153.         mov eax,WM_CUT
    154.         jmp sendt
    155.  UNDO:
    156.         mov eax,EM_UNDO
    157.  sendt:
    158.         invoke SendMessage,[edith],eax,0,0
    159.         ret
    160.  
    161.  NEW:
    162.      call [saving]
    163.      mov [newflag],1
    164.      invoke SendMessage,[edith],WM_SETTEXT,0,0;ïîñûëàåì Edit'ó ïóñòîé WM_SETTEXT
    165.      ret
    166.  
    167.  ABOUT:
    168.       invoke MessageBox,[hwnd],'RFpad text editor by Adrax','RFpad',MB_OK
    169.       ret
    170.  
    171.  OPEN:
    172.       call [saving]
    173.       mov [ofn.Flags],OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_EXPLORER
    174.       invoke GetOpenFileName,ofn
    175.       test eax,eax
    176.       jz fileopenfailed
    177.  
    178.   getopen:
    179.           invoke CreateFile,buffer,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,0;îòêðûâàåì ôàéë
    180.         mov edi,eax
    181.         invoke GetFileSize,edi,0
    182.         mov [filesize],eax
    183.         invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,eax;âûäåëÿåì ïàìÿòü èç êó÷è
    184.         mov [hmem],eax
    185.         invoke GlobalLock,eax
    186.         mov [pmem],eax
    187.         invoke ReadFile,edi,[pmem],[filesize]-1,sizeRW,0
    188.         invoke SendMessage,[edith],WM_SETTEXT,0,[pmem]
    189.         invoke GlobalUnlock,[pmem]
    190.         invoke GlobalFree,[hmem]
    191.         invoke CloseHandle,edi
    192.         mov [newflag],1
    193.   fileopenfailed:
    194.         invoke SetFocus,[edith]
    195.         ret
    196.  
    197.  SAVE:
    198.        cmp [newflag],1
    199.        jz getsave
    200.  SAVEAS:
    201.        mov [ofn.Flags],OFN_EXPLORER or OFN_OVERWRITEPROMPT
    202.        invoke GetSaveFileName,ofn
    203.        test eax,eax
    204.        jz filesavefailed
    205.   getsave:
    206.        invoke CreateFile,buffer,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,0
    207.        mov edi,eax
    208.        invoke SendMessage,[edith],EM_GETTEXTLENGTHEX,0,0
    209.        mov [filesize],eax
    210.        invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,[filesize]
    211.        mov [hmem],eax
    212.        invoke GlobalLock,eax
    213.        mov [pmem],eax
    214.        invoke SendMessage,[edith],WM_GETTEXT,[filesize]-1,eax      
    215.        invoke WriteFile,edi,[pmem],eax,sizeRW,0
    216.        invoke GlobalUnlock,[pmem]
    217.        invoke GlobalFree,[hmem]
    218.        invoke CloseHandle,edi
    219.        invoke SendMessage,[edith],EM_SETMODIFY,0,0
    220.        mov [newflag],0
    221. filesavefailed:
    222.         invoke SetFocus,[edith]
    223.         ret
    224.  
    225.  EXIT:
    226.       call saving
    227.       invoke DestroyWindow,[hwnd]
    228.       ret
    229.  
    230.  Siz:
    231.       invoke GetClientRect,[hwnd],client
    232.       invoke MoveWindow,[edith],[client.left],[client.top],[client.right],[client.bottom],TRUE
    233.       xor eax,eax
    234.       jmp finish
    235.  
    236.  Act:
    237.       invoke SetFocus,[edith]
    238.       xor eax,eax
    239.       jmp finish
    240.  
    241.  saving:
    242.       invoke SendMessage,[edith],EM_GETMODIFY,0,0
    243.         test eax,eax
    244.         jz not_modified
    245.         invoke MessageBox,[hwnd],changes,name,MB_YESNO + MB_ICONWARNING
    246.         cmp eax,IDYES
    247.         jne not_modified
    248.         call SAVE
    249. not_modified:
    250.         ret
    251.  
    252.   Destroy:
    253.         invoke  PostQuitMessage,0
    254.         xor eax,eax
    255.  
    256.  
    257.   finish:
    258.         pop edi
    259.         pop esi
    260.         pop ebx
    261.         ret
    262. endp
    263.  
    264. section '.rsrc' resource from 'RFpad.res' data  readable
    265.  
    266. .end fuck
    Как вы уже, наверное, догадались - это попытка сделать из примера minipad аналог блокнота:)
    Но вот натолкнулся на эту проблемку с таблицей смещений... И что-то я с accelerators перемудрил - горячие клавиши не действуют:dntknw:
     
  5. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    Какие значения принимает wparam перед
    Код (Text):
    1. ...
    2. mov eax,[wparam]
    3. cmp ax,100h
    4. jb continue
    5. ...
    от 101h и больше?
     
  6. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 q_q
    От 100h и выше
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ну и чему же тогда равно table+eax*4 ?
    Нужно либо sub вместо cmp, либо [table+eax*4-100h]
     
  8. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    От 100h и выше
    Покажи RC-скрипт, def'ыв, а то еще окажется, что IDM'мы не попорядку.

    leo
    -100h или -400h?
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Идентификаторы команд NEW, OPEN и прочие должны быть последовательными и, как сказал leo, нужно отнимать от EAX значение наименьшего идентификатора.

    А как работал код на масме-то? Или он не работал?
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    q_q
    Упс, ес-но -100h*4 = -400h
    Но лучше sub вместо cmp, т.к. значение eax дальше не используется
     
  11. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    IceStudent
    А как работал код на масме-то?
    Imho тема о доработке %FASMROOT%\EXAMPLES\MINIPAD, а masmупомянут в связи с наличеим в нем оператора offset.
     
  12. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 q_q
    Ну, я ж не совсем двинутый ещё... Ясен палец, что в .rc все IDM по порядку:)

    Да-да, именно фасмовский minipad имелся в виду! А табличку со смещениями я почерпнул из какого-то тутора по masm и не знал, сработает ли это в fasm

    2 leo
    -100h
    Блиииин, спасибо! Йа криведко:dntknw:

    Всё равно что-то непонятно:dntknw:
    Заменил cmp eax,100h на sub eax,100h - заработали меню Edit и About, но пункты меню File не вызывают никакой реакции у программы...кроме вылета...
    И горячие клавиши не хотят работать... Где косячу??

    Выкладываю заодно и .rc - мож, там где-то ошибся?
    Код (Text):
    1. #define IDM_NEW             0x100L
    2. #define IDM_OPEN            0x101L
    3. #define IDM_SAVE            0x102L
    4. #define IDM_SAVEAS          0x103L
    5. #define IDM_EXIT            0x104L
    6. #define IDM_ABOUT           0x105L
    7. #define IDM_UNDO            0x106L
    8. #define IDM_CUT             0x107L
    9. #define IDM_COPY            0x108L
    10. #define IDM_PASTE           0x109L
    11. #define IDM_CLEAR           0x10AL
    12. #define IDM_SETSEL          0x10BL
    13.  
    14. #define ID_MENU             0x700L
    15. #define ID_ACCEL            0x701L
    16. #define ID_ABOUT            0x702L
    17. #define ID_ICON             0x703L
    18. ID_ICON ICON "1.ico"
    19. ID_MENU MENU DISCARDABLE {
    20.         POPUP "&File" {
    21.                 MENUITEM "&New\tCtrl+N", IDM_NEW
    22.                 MENUITEM "&Open...\tCtrl+O", IDM_OPEN
    23.                 MENUITEM "&Save\tCtrl+S", IDM_SAVE
    24.                 MENUITEM "Save &As...\tCtrl+Shift+S", IDM_SAVEAS
    25.                 MENUITEM SEPARATOR
    26.                 MENUITEM "E&xit\tCtrl+Q", IDM_EXIT
    27.         }
    28.         POPUP "&Edit" {
    29.                 MENUITEM "&Undo\tCtrl-Z", IDM_UNDO
    30.                 MENUITEM SEPARATOR
    31.                 MENUITEM "Cu&t\tCtrl-X", IDM_CUT
    32.                 MENUITEM "&Copy\tCtrl-C", IDM_COPY
    33.                 MENUITEM "&Paste\tCtrl-V", IDM_PASTE
    34.                 MENUITEM "&Delete\tDel", IDM_CLEAR
    35.                 MENUITEM SEPARATOR
    36.                 MENUITEM "Select &All\tCtrl-A", IDM_SETSEL
    37.         }
    38.         POPUP "&Help" {
    39.                 MENUITEM "About", IDM_ABOUT
    40.         }
    41. }
    42. ID_ACCEL ACCELERATORS DISCARDABLE {
    43.         "N", IDM_NEW, CONTROL, VIRTKEY
    44.         "O", IDM_OPEN, CONTROL, VIRTKEY
    45.         "S", IDM_SAVE, CONTROL, VIRTKEY
    46.         "S", IDM_SAVEAS, CONTROL, SHIFT, VIRTKEY
    47.         "Q", IDM_EXIT, CONTROL, VIRTKEY
    48.         "Z", IDM_UNDO, CONTROL, VIRTKEY
    49.         "A", IDM_SETSEL, CONTROL, VIRTKEY
    50. }
     
  13. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    вызывают никакой реакции у программы...кроме вылета...
    1) Не все WM_COMMAND надо пропускать через call dword [table+eax*4] (подробности на msdn/psdk), например, можно добавить
    Код (Text):
    1. ...
    2.     cmp [lparam],0      ;; !
    3.     jnz continue        ;; !
    4.     mov eax,[wparam]
    5.     sub eax,100h
    6. ;;        cmp ax,100h
    7.     jb continue    
    8.     cmp eax,0Bh     ;; !
    9.     ja continue     ;; !
    10.     call dword [table+eax*4]
    11.     jmp continue
    12. ...
    2) Пришла пора посмотреть на генерируемый код . Наличие call XXX внутри proc Procedura приводит к катастрофическим последствиям.
    Код (Text):
    1. ...
    2. proc Procedura hwnd,wmsg,wparam,lparam
    3.     push ebx
    4.     push esi
    5.     push edi
    6. ...
    7.     call    saving
    8. ...
    9.  saving:
    10.     invoke SendMessage,[edith],EM_GETMODIFY,0,0
    11.     test eax,eax
    12.     jz not_modified
    13.     invoke MessageBox,[hwnd],changes,name,MB_YESNO + MB_ICONWARNING
    14.     cmp eax,IDYES
    15.     jne not_modified
    16.     call SAVE
    17. not_modified:
    18.     ret
    19.   finish:
    20.     pop edi
    21.     pop esi
    22.     pop ebx
    23.     ret
    24. endp
    генерирует
    Код (Text):
    1. ...
    2. 004024B8 /$ 6A 00         PUSH 0                      ; /lParam = 0
    3. 004024BA |. 6A 00         PUSH 0                      ; |wParam = 0
    4. 004024BC |. 68 B8000000   PUSH 0B8                    ; |Message = EM_GETMODIFY
    5. 004024C1 |. FF35 C1114000 PUSH DWORD PTR DS:[4011C1]  ; |hWnd = NULL
    6. 004024C7 |. FF15 0C424000 CALL USER32.SendMessageA
    7. 004024CD |. 85C0          TEST EAX,EAX
    8. 004024CF |. 74 1F         JE SHORT t.004024F0
    9. 004024D1 |. 6A 34         PUSH 34                     ; /Style = MB_YESNO|MB_ICONEXCLAMATION|MB_APPLMODAL
    10. 004024D3 |. 68 00104000   PUSH t.00401000             ; |Title = "RFpad"
    11. 004024D8 |. 68 0B104000   PUSH t.0040100B             ; |Text = "Do you want to save changes?"
    12. 004024DD |. FF75 08       PUSH DWORD PTR SS:[EBP+8]
    13. 004024E0 |. FF15 FC414000 CALL USER32.MessageBoxA
    14. 004024E6 |. 83F8 06       CMP EAX,6
    15. 004024E9 |. 75 05         JNZ SHORT t.004024F0
    16. 004024EB |. E8 7CFEFFFF   CALL t.0040236C
    17. 004024F0 |> C9            LEAVE                        ;; !!! где pop edi esi ebx ?
    18. 004024F1 \. C2 1000       RETN 10                      ;; !!! где ret из saving?
    19. ...
    ps По сравнению с w9x, w2k & wxp терпят такое поведение оконной процедуры, но всему есть предел.
     
  14. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 q_q
    Спасибо!
    Блин, как меня угораздило ret забыть?

    А с Accelerators я где протупил, не подскажете?
     
  15. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 q_q
    Имхо, ret'ов хватает:) Бегло пробежался взглядом по коду: сколько call'ов - столько ret'ов
    В приведенном вами участке кода выход не из Procedura, а как раз из saving...

    Странно получается: менюшки Edit и About работают...
    При нажатии на New или Exit, а также кнопку "закрыть" в заголовке - реакции никакой абсолютно. Как оказалось, в обработчиках NEW и EXIT код после call saving управления не получает... Я никак не пойму, с чем это связано:dntknw:

    Если же нажать Save, прога вылетает при попытке записи по нулевому указателю, причём отладчик забрасывает в самые глубины user32.dll... Никакой логики не вижу...

    Понимаю, что всё гнездится в saving и SAVE, но никак не пойму, в чём ошибка?
     
  16. JAPH

    JAPH New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2007
    Сообщения:
    124
    Ret`ов вам хватает... Только q_q указывает на следующее:
    в исходнике (возле not_modified) ret, а после трансляции там
    leave ; а где создавался кадр стэка?!
    retn 10h ; и откуда 4 параметра?!
    Нужно, чтобы эта инструкция транслировалась как простая retn.
     
  17. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    Имхо, ret'ов хватает
    JAPH все сказал. Можно заменить все ret'ы, кроме финишного, на db 0C3h, "чтобы эта инструкция транслировалась как простая retn" (C) JAPH. Это на какое-то время решит проблему вылетов.

    Что касается неработоспособности open и save, то для начала проблема в неверном OPENFILENAME.lStructSize. Должно быть 4Ch, а у тебя 28h.

    А с Accelerators ... не подскажете?
    Разберешься с меню, чтением/записью файла, перейдем к акселераторам.
     
  18. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Adrax, q_q
    Вопрос о ret очень древний и обсуждался много раз: внутри proc..endp происходит подмена инструкции ret на макрос ret (~ leave+retn), поэтому в качестве инструкции C3h нужно использовать retn
     
  19. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Не проще ли использовать для прыжка JMP, а не CALL? :)
     
  20. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    IceStudent
    Для saving не получится.